List 3-12およびList 3-14は会員番号をキー値としている。氏名をキー値にしたプログラムを作成せよ。 |
// 演習3-7 // (a) チェイン法によるハッシュの利用例(キーは氏名) import java.util.Scanner; class ChainHashTester2 { static Scanner stdIn = new Scanner(System.in); //--- データ(会員番号+氏名) ---// static class Data { public final static int NO = 1; // 番号を読み込むか? public final static int NAME = 2; // 氏名を読み込むか? Integer no; // 会員番号(キー値) String name; // 氏名 //--- キー値 ---// public Integer keyCode() { return name.hashCode(); } //--- 文字列表現を返す ---// public String toString() { return name; } //--- 会員番号を文字列表現で返す ---// public String getNo() { return no.toString(); } //--- データの読込み ---// public void scanData(String guide, int sw) { System.out.println(guide + "するデータを入力してください。"); if ((sw & NO) == NO) { System.out.print("番号:"); no = stdIn.nextInt(); } if ((sw & NAME) == NAME) { System.out.print("名前:"); name = stdIn.next(); } } } //--- メニュー列挙型 ---// public enum Menu { ADD( "データ追加"), REMOVE( "データ削除"), SEARCH( "データ探索"), DUMP( "全データ表示"), TERMINATE("終了"); private final String message; // 表示用文字列 static public Menu MenuAt(int idx) { // 序数がidxである列挙を返す for (Menu m : Menu.values()) if (m.ordinal() == idx) return m; return null; } Menu(String string) { // コンストラクタ message = string; } public String getMessage() { // 表示用文字列を返す return message; } } //--- メニュー選択 ---// static Menu SelectMenu() { int key; do { for (Menu m : Menu.values()) { System.out.printf("(%d) %s ", m.ordinal(), m.getMessage()); if ((m.ordinal() % 3) == 2 && m.ordinal() != Menu.TERMINATE.ordinal()) System.out.println(); } System.out.print(":"); key = stdIn.nextInt(); } while (key < Menu.ADD.ordinal() || key > Menu.TERMINATE.ordinal()); return Menu.MenuAt(key); } public static void main(String[] args) { Menu menu; // メニュー Data data; // 追加用データ参照 Data temp = new Data(); // 読込み用データ ChainHash<Integer, Data> hash = new ChainHash<Integer, Data>(13); do { switch (menu = SelectMenu()) { case ADD : data = new Data(); // 追加 data.scanData("追加", Data.NO | Data.NAME); hash.add(data.keyCode(), data); break; case REMOVE : // 削除 temp.scanData("削除", Data.NAME); hash.remove(temp.keyCode()); break; case SEARCH : // 探索 temp.scanData("探索", Data.NAME); Data t = hash.search(temp.keyCode()); if (t != null) System.out.println("そのキーをもつ会員番号は" + t.getNo() + "です。"); else System.out.println("該当するデータはありません。"); break; case DUMP : // 表示 hash.dump(); break; } } while (menu != Menu.TERMINATE); } }
// 演習3-7 // (b) オープンアドレス法によるハッシュの利用例(キーは氏名) import java.util.Scanner; class OpenHashTester2 { static Scanner stdIn = new Scanner(System.in); //--- データ(会員番号+氏名) ---// static class Data { public final static int NO = 1; // 番号を読み込むか? public final static int NAME = 2; // 氏名を読み込むか? Integer no; // 会員番号(キー値) String name; // 氏名 //--- キー値 ---// public Integer keyCode() { return name.hashCode(); } //--- 文字列表現を返す ---// public String toString() { return name; } //--- 会員番号を文字列表現で返す ---// public String getNo() { return no.toString(); } //--- データの読込み ---// public void scanData(String guide, int sw) { System.out.println(guide + "するデータを入力してください。"); if ((sw & NO) == NO) { System.out.print("番号:"); no = stdIn.nextInt(); } if ((sw & NAME) == NAME) { System.out.print("名前:"); name = stdIn.next(); } } } //--- メニュー列挙型 ---// public enum Menu { ADD( "データ追加"), REMOVE( "データ削除"), SEARCH( "データ探索"), DUMP( "全データ表示"), TERMINATE("終了"); private final String message; // 表示用文字列 static public Menu MenuAt(int idx) { // 序数がidxである列挙を返す for (Menu m : Menu.values()) if (m.ordinal() == idx) return m; return null; } Menu(String string) { // コンストラクタ message = string; } public String getMessage() { // 表示用文字列を返す return message; } } //--- メニュー選択 ---// static Menu SelectMenu() { int key; do { for (Menu m : Menu.values()) { System.out.printf("(%d) %s ", m.ordinal(), m.getMessage()); if ((m.ordinal() % 3) == 2 && m.ordinal() != Menu.TERMINATE.ordinal()) System.out.println(); } System.out.print(":"); key = stdIn.nextInt(); } while (key < Menu.ADD.ordinal() || key > Menu.TERMINATE.ordinal()); return Menu.MenuAt(key); } public static void main(String[] args) { Menu menu; // メニュー Data data; // 追加用データ参照 Data temp = new Data(); // 読込み用データ OpenHash<Integer, Data> hash = new OpenHash<Integer, Data>(13); do { switch (menu = SelectMenu()) { case ADD : data = new Data(); // 追加 data.scanData("追加", Data.NO | Data.NAME); int k = hash.add(data.keyCode(), data); switch (k) { case 1: System.out.println("そのキー値は登録済みです。"); break; case 2: System.out.println("ハッシュ表が満杯です。"); break; } break; case REMOVE : // 削除 temp.scanData("削除", Data.NAME); hash.remove(temp.keyCode()); break; case SEARCH : // 探索 temp.scanData("探索", Data.NAME); Data t = hash.search(temp.keyCode()); if (t != null) System.out.println("そのキーをもつ会員番号は" + t.getNo() + "です。"); else System.out.println("該当するデータはありません。"); break; case DUMP : // 表示 hash.dump(); break; } } while (menu != Menu.TERMINATE); } }