⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 librarysystem.java

📁 国外的数据结构与算法分析用书
💻 JAVA
字号:
package library;

import dslib.list.BilinkedListUos;
import dslib.dictionary.arrayed.ArrayedPKeyedBasicDictUos;
import dslib.base.*;
import java.io.*;
import dslib.exception.*;

/**	The library system to handle the borrowing and returning of  books.   In particular, 
	it keeps track of books on loan so that overdue notices can be sent out efficiently. */
public class LibrarySystem
{
	/**	A list of overdue books. */
	private BilinkedListUos overdueList;

	/**	A list for each day of the books due back that day. */
	private BilinkedListUos[] onLoanLists;

	/**	A constant to store the number of days in a year. */
	private final int YEAR_LENGTH = 366;

	/**	A constant recording the current upper bound for the number of books. */
	private final int MAX_NUM_OF_BOOKS = 10;

	/**	A dictionary of all books in the library with access by isbn number. */
	private ArrayedPKeyedBasicDictUos books;
		
	/**	The date today. */
	private int date;

	/**	The next day for which overdue notices need to be printed. */
	private int nextDayToPrint;

	/**	Initialize the library system: the lists, the current date, and the books dictionary.
		Analysis: Time = O(max(YEAR_LENGTH, MAX_NUM_OF_BOOKS)) */
	public LibrarySystem()
	{
		overdueList = new BilinkedListUos();
		onLoanLists = new BilinkedListUos[YEAR_LENGTH];
		for (int i = 0; i < YEAR_LENGTH; i++)
			onLoanLists[i] = new BilinkedListUos();
		date = 1;
		nextDayToPrint = date;
		books = new ArrayedPKeyedBasicDictUos(MAX_NUM_OF_BOOKS); 
	}

	/**	Add a new book into the library.
		Analysis: Time = O(books.count) i.e., time to insert a book into the dictionary 
		PRECONDITION:
			!books.isFull()
			!books.has(isbn) */
	public void addBook(String title, String author, String isbn) throws ContainerFullUosException, DuplicateItemsUosException
	{
		if (books.isFull())
			throw new ContainerFullUosException("Cannot add a book when the book dictionary is full.");
		if (books.has(isbn))
			throw new DuplicateItemsUosException("Cannot add a book with the same isbn as an existing book");
	
		LibraryBook newBook = new LibraryBook(title, author, isbn);
		books.insert(isbn, newBook);
	}

	/**	Remove the 'isbn' book from the library.
		Analysis: Time = O(books.count) i.e., time to delete a book from the dictionary 
		PRECONDITION:
			books.has(isbn) */
	public void removeBook(String isbn) throws ItemNotFoundUosException
	{
		if (!books.has(isbn))
			throw new ItemNotFoundUosException("Cannot delete a book that is not in the dictionary.");
	
		books.delete(isbn);
	}

	/**	Carry out the borrowing of the `isbn' book by patron `p'.
		Analysis: Time = O(log(books.count)) i.e., time to obtain the book 
		PRECONDITION:
			books.has(ibsn) */
	public void borrowBook(String isbn, Patron p) throws ItemNotFoundUosException, BookOnLoanException
	{
		if (!books.has(isbn))
			throw new ItemNotFoundUosException("Cannot borrow a book that is not in the library.");

		LibraryBook b = (LibraryBook)books.obtain(isbn);
		if (b.isOnLoan())
			throw new BookOnLoanException("Cannot borrow a book already on loan.");

		int dd = dueDate();
		p.borrowBook(b);
		b.borrowed(p, dd);
		onLoanLists[dd - 1].insertGo(b);
		b.setPosition(onLoanLists[dd - 1].currentPosition());
	}

	/**	Carry out the return of the `isbn' book.
		Analysis: Time = O(log(books.count)) i.e., time to obtain the book
		PRECONDITION:
			books.has(isbn) */
	public void returnBook(String isbn) throws ItemNotFoundUosException, BookNotOnLoanException
	{
		if (!books.has(isbn))
			throw new ItemNotFoundUosException("Cannot return a book that is not in the library.");

		LibraryBook b = (LibraryBook)books.obtain(isbn);
		if (!b.isOnLoan())
			throw new BookNotOnLoanException("Cannot return a book not on loan.");

		Patron p = b.onLoanTo;
		BilinkedListUos listOfBooks;
		if (b.isOverdue)
		{
			printOverdueCharges(b);
			listOfBooks = overdueList;
		}
		else
			listOfBooks = (BilinkedListUos)onLoanLists[b.dueDate - 1];
		listOfBooks.goPosition(b.position);
		listOfBooks.deleteItem();
		p.returnBook(b);
		b.returned();
	}

	/**	Print overdue notices and start of month reminder notices. 
		Analysis: Time = O(n), where n = number of notices printed */
	public void printNotices()
	{
		int printStart = nextDayToPrint;
		printFirstNotices(printStart); 	// print overdue notices from printStart to yesterday
		nextDayToPrint = date;

		/*	Print start of month reminders if a month started during the period being printed. */
		int printEnd = date - 1;
		if (printEnd == 0)
			printEnd = YEAR_LENGTH;
		if (containsMonthStart(printStart, printEnd))
			printReminderNotices();
	}

	/**	Print a reminder notice for those books more than 15 days overdue.
		Analysis: Time = O(k), where k = length of the overdue list */
	public void printReminderNotices()
	{
		overdueList.goFirst();
		while (!overdueList.after())
		{
			LibraryBook curBook = (LibraryBook)overdueList.item();
			if (daysOverdue(curBook) >= 15)
				printOverdue(curBook, "reminder");
			overdueList.goForth();
		}
	}

	/**	Print overdue notices for books which just became overdue.
		Analysis: Time = O(p), where p = number of notices printed */
	public void printFirstNotices(int printStart)
	{
		/*	Print notices from day = printStart until date - 1. */
		for (int d = printStart; d != date; d++)
		{
			if (d == YEAR_LENGTH + 1)
				d = 1;	
			/*	Print the notices for books due on date d. */
			BilinkedListUos list = onLoanLists[d-1];
			list.goFirst();
			while (!list.after())
			{
				LibraryBook b = (LibraryBook)list.item();
				printOverdue(b, "first");
				list.deleteItem();
				overdueList.insertGo(b);
				b.setPosition(overdueList.currentPosition());
				b.setOverdue();
				/*	Don't include list.goForth as deleteItem advances to next item. */
			}
		}
	}

	/**	Compute the date that the book is due.
		Analysis: Time = O(1) */
	public int dueDate()
	{
		int result = date + 21;
		if (result > YEAR_LENGTH)
			result -= YEAR_LENGTH;
		return result;
	}

	/** 	Compute the number of days book `b' is overdue.
		Analysis: Time = O(1) */
	public int daysOverdue(LibraryBook b)
	{
		int result = date - b.dueDate;
		if (result <= 0)
			result += YEAR_LENGTH;
		return result;
	}

	/** 	Compute the late charges for book `b'.  
		Analysis: Time = O(1) */
	public double computeCharges(LibraryBook b)
	{
		return daysOverdue(b) * 0.5;
	}

	/** 	Set the date.
		Analysis: Time = O(1) */
	public void setDate(int x)
	{
		date = x;
	}

	/**	The day of the month. */
	private int monthDay;

	/**	Dummy function for testing purposes.
		Assumes 5 working days (calls to printNotices) per month */
	public boolean containsMonthStart(int d1, int d2)
	{
		boolean found = false;
		monthDay++;
		if (monthDay == 5) 
		{
			found = true;
			monthDay = 0;
		}
		return found;
	}

	/**	Writer for debug */
	PrintWriter outfile;
	
	/**	Set the writer for debugging purposes */
	public void setWriter(PrintWriter newOutFile)
	{
		outfile = newOutFile;
	}

	/**	Print the late charges for book `b'.
		Analysis: Time = O(1) */
	public void printOverdueCharges(LibraryBook b)
	{
		outfile.println("\nreturn of overdue book:  " + b.toString() 
								+ "\n" + "  Late charges amount to:  $" + computeCharges(b));
	}

	/**	Print out the late notice of a specific type for book `b'.
		Analysis: Time = O(1) */
	public void printOverdue(LibraryBook b, String type)
	{
		outfile.println("\nOVERDUE NOTICE for day " + date + " ---------------" 
							+ "\n" + b.toString() + "\n  Type of notice: " + type);
	}

	/** 	String representation of all library current information, including the books 
		in the library, the books on loan, and the books that are overdue.
		Analysis: Time = O(n+m+p), where n = number of books in the library, 
		m = number of books on loan, and p = number of overdue books */
	public String toString()
	{
		String result = "\n........... Library status on day " + date + " ............" 
					+ "\nBooks of the library \n" + books.toString() + "\nOn loan lists";
	
		for (int i = 0; i < YEAR_LENGTH; i++)
			if (!onLoanLists[i].isEmpty())
			{
				result += " \nList " + (i+1) + " contents *************************"
					+ "\n" + onLoanLists[i].toString();
			}
		
		result += "\n\nOverdue list contents *************************";
				
		if (overdueList.isEmpty())
			result += "\n  No overdue books.\n";
		else
			result += "\n" + overdueList.toString();
			
		result += "\n........... End library status .........\n";
		return result;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -