基本情報技術者試験 平成15年度・春期・午後 問12 ソースプログラム
public class ListElement {
private ListElement prev, next;
public ListElement() {
prev = next = this;
}
public ListElement nextElement() { return next; }
public ListElement previousElement() { return prev; }
public void insertBefore(ListElement element) {
next = element;
prev = element.prev;
next.prev = prev.next = this;
}
public void remove() {
prev.next = next;
next.prev = prev;
prev = next = this;
}
}
public class Seat extends ListElement {
private String userID; // 使用者
private long checkinTime; // 使用開始時刻
private int seatNumber; // 座席番号
public Seat(int seatNumber) {
this.seatNumber = seatNumber;
}
public int getSeatNumber() {
return seatNumber;
}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public boolean isUsedBy(String userID) {
return this.userID.equals(userID);
}
public long getCheckinTime() {
return checkinTime;
}
public void setCheckinTime(long time) {
checkinTime = time;
}
}
public class SeatManager {
private static final int NSEATS = 30; // 席数
// 最大使用時間〔ミリ秒〕
private static final int MAXTIME = 60 * 60 * 1000;
// 空席リスト
private ListElement freeSeats = new ListElement();
// 使用中リスト
private ListElement occupiedSeats = new ListElement();
public SeatManager() {
for (int i = 1; i <= NSEATS; i++) {
Seat seat = new Seat(i);
seat.insertBefore(freeSeats);
}
}
// 空席リストに空席があればその Seat インスタンスを空席リストから
// 削除し,そのインスタンスを返す。空きがなければ null を返す。
private Seat getFreeSeat() {
ListElement le = freeSeats.nextElement();
if (le != freeSeats) {
le.remove();
return (Seat) le;
}
return null;
}
// 使用中リストを調べ,最大使用時間を超えて席を使用している
// 使用者がいれば,その旨出力し,checkout を呼ぶ。
private void vacateExpiredSeat(long time) {
ListElement le = occupiedSeats.previousElement();
if (le != occupiedSeats) {
Seat seat = (Seat) le;
if ((seat.getCheckinTime() + MAXTIME) < time) {
System.out.println("Seat#" +
seat.getSeatNumber() + " " +
seat.getUserID() +
" must check out.");
checkout(seat.getUserID());
}
}
}
// 使用中リストから指定された使用者が使っている席を探し,見つかれば
// その席を,見つからなければ null を返す。
private Seat findUser(String userID) {
ListElement le = occupiedSeats.nextElement();
while (le != occupiedSeats) {
Seat seat = (Seat) le;
if (seat.isUsedBy(userID)) {
return seat;
}
le = le.nextElement();
}
return null;
}
public Seat checkin(String userID) {
long now = System.currentTimeMillis();
Seat seat = getFreeSeat();
if (seat == null) {
vacateExpiredSeat(now);
seat = getFreeSeat();
}
if (seat != null) {
seat.setCheckinTime(now);
seat.setUserID(userID);
seat.insertBefore(occupiedSeats.nextElement());
}
return seat;
}
public boolean checkout(String userID) {
Seat seat = findUser(userID);
if (seat != null) {
seat.remove();
seat.setUserID(null);
seat.insertBefore(freeSeats);
return true;
}
return false;
}
}