• 締切済み

バイナリサーチです

javaプログラムで、 プログラム中に10人分の番号、氏名、電話番号を書き、 二文探索を使って、番号or氏名から電話番号を検索する というプログラムを作っています。 テキスト頼りに自分でやってきたのですが、 コンパレータなどの意味が分からず どう使えばよいか分かりません 途中まではやってみたのですが、ここまでも合ってるか分かりません 二文探索の方法についてご教授願います import java.util.Arrays*; import java.util.Scanner*; import java.util.Comparators*; class search { static class 10data { private int number; //番号 private String name; //名前 private String phonenumber; //電話番号 public 10data(int number, String name, String phonenumber) { this.number = number; this.name = name; this.phonenumber = phonenumber; } public String toString() { return number + "" + name + "" + phonenumber; } public static void main(String[] args) { Scanner stdln = new Scanner(System.in); 10data[] x = { new P_Data(01,akai,9147965416), new P_Data(02,akiyama,9274621646), new P_Data(03,katayama,5695195617), new P_Data(04,kato,8414817863), new P_Data(05,sakamoto,9548614769), new P_Data(06,sato,1819316141), new P_Data(07,tanaka,3215468548), new P_Data(08,tani,6456212314), new P_Data(09,nakanishi,6865148642), new P_Data(10,nakamura,3136467825), }; System.out.print("誰の電話番号を検索?生徒番号or名前:");

みんなの回答

回答No.3

>入力メソッドもよくわからないのですが・・・入力するのはinputstreamreaderでよいのでしょうか 元のソースでScannerオブジェクトが生成されていましたから、 てっきりそれを使って実装する予定なのだろうと思っていました。 特に使用するAPIに指定が無く、特殊な読み方をしたいわけでなければBufferedReaderでラップしたInputStreamReaderで問題ないです。 >番号or名前ならString name = br.readLine();ではだめですよね そこは個々のプログラムの実装依存ですので、プログラマが制御してやらないとだめです。 これも特に指定が無いようなら、例として以下の様な方法を提示してみます。 System.out.println("誰の電話番号を検索?生徒番号or名前"); System.out.print("(数値:生徒番号検索、数値以外:名前検索、未入力:処理終了):"); //入力 String input; try { search._10data keyObj; int index; for (BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); ((input = br.readLine()) != null) && input.length() > 0;) { try { int num = Integer.parseInt(input); keyObj = new search._10data(num, null, null); search.NumberComp numComp = new search.NumberComp(); Arrays.sort(x, numComp); index = Arrays.binarySearch(x, keyObj, numComp); if (index > -1) { System.out.println("生徒番号検索の該当データ⇒" + x[index]); }else System.out.println("生徒番号検索の該当無し"); }catch(NumberFormatException e) { String name = input; keyObj = new search._10data(0, name, null); search.NameComp nmComp = new search.NameComp(); Arrays.sort(x, nmComp); index = Arrays.binarySearch(x, keyObj, nmComp); if (index > -1) { System.out.println("名前検索の該当データ⇒" + x[index]); }else System.out.println("名前検索の該当無し"); } System.out.print("(数値:生徒番号検索、数値以外:名前検索、未入力:処理終了):"); } System.out.println("処理を終了します。"); }catch(IOException e){System.err.println(e);}

回答No.2

前回の回答、コメント中に嘘がありましたので訂正します。申し訳ありません。 >* 引数1のソートキー < 引数2のソートキー⇒戻り値=-1 >* 引数1のソートキー == 引数2のソートキー⇒戻り値=0 >* 引数1のソートキー > 引数2のソートキー⇒戻り値=1 上記を以下の様に訂正 引数1のソートキー < 引数2のソートキー⇒戻り値=負の整数 引数1のソートキー == 引数2のソートキー⇒戻り値=0 引数1のソートキー > 引数2のソートキー⇒戻り値=正の整数

rondrond22
質問者

補足

import java.util.*; import java.io.*;//java.io クラスをインポートします public class search { static class _10data { private int number; //番号 private String name; //名前 private String phonenumber; //電話番号 public _10data(int number, String name, String phonenumber) { this.number = number; this.name = name; this.phonenumber = phonenumber; } public String toString() { return number + "" + name + "" + phonenumber; } public static void main(String args[]) throws IOException { Scanner stdln = new Scanner(System.in); _10data[] x = { new search._10data(2,"akiyama","9274621646"), new search._10data(1,"akai","9147965416"), new search._10data(4,"kato","8414817863"), new search._10data(5,"sakamoto","9548614769"), new search._10data(8,"tani","6456212314"), new search._10data(7,"tanaka","3215468548"), new search._10data(3,"katayama","5695195617"), new search._10data(6,"sato","1819316141"), new search._10data(9,"nakanishi","6865148642"), new search._10data(10,"nakamura","3136467825") }; System.out.print("誰の電話番号を検索?生徒番号or名前:"); //入力は実装済みと仮定する。 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String name = br.readLine(); (略) 入力メソッドもよくわからないのですが・・・入力するのはinputstreamreaderでよいのでしょうか 番号or名前ならString name = br.readLine();ではだめですよね

回答No.1

元の状態でコンパイルエラーがたくさんありました。 ・インポートの*の使い方が不正でした。 ・識別子が不正でした。(識別子の先頭に使える文字はアルファベットと_と$だけです) ・ネストクラスのインスタンス生成の方法が不正でした。(生成時の名前の不一致もあり) ・リテラルが不正でした。(不正な8進数、文字列が""で囲われていない) ・ネストが不正でした。 等、少し気になりましたが、とりあえずあまり元の構造を変えないようにいじってみました。(それでも結構こまごま変わってしまいましたが・・・) ソースの解説はコメントに書きましたので、わかりにくければすみません。 import java.util.*; public class search { static class _10data { private int number; //番号 private String name; //名前 private String phonenumber; //電話番号 public _10data(int number, String name, String phonenumber) { this.number = number; this.name = name; this.phonenumber = phonenumber; } public String toString() { return number + "" + name + "" + phonenumber; } public static void main(String[] args) { Scanner stdln = new Scanner(System.in); _10data[] x = { new search._10data(2,"akiyama","9274621646"), new search._10data(1,"akai","9147965416"), new search._10data(4,"kato","8414817863"), new search._10data(5,"sakamoto","9548614769"), new search._10data(8,"tani","6456212314"), new search._10data(7,"tanaka","3215468548"), new search._10data(3,"katayama","5695195617"), new search._10data(6,"sato","1819316141"), new search._10data(9,"nakanishi","6865148642"), new search._10data(10,"nakamura","3136467825") }; System.out.print("誰の電話番号を検索?生徒番号or名前:"); //入力は実装済みと仮定する。 System.out.println(); //生徒番号検索で9を指定された場合、生徒番号検索キーとして_10dataのインスタンスをnumber=9で生成 search._10data keyObj = new search._10data(9,null, null); //生徒番号ソート、二分探索用のコンパレータのインスタンスを生成 search.NumberComp numComp = new search.NumberComp(); //生徒番号でソート(※binarySearchメソッドは事前に同条件でソートされていないと正しい結果を返せないので先にソートをかけています) Arrays.sort(x, numComp); //二分探索で該当したインデックスを取得(該当しなかった場合は不の値が戻る) int index = Arrays.binarySearch(x, keyObj, numComp); if (index > -1) { //該当したインデックスに紐付く情報を出力 System.out.println("生徒番号検索の該当データ⇒" + x[index]); }else System.out.println("生徒番号検索の該当無し"); //名前検索でkatayamaを指定された場合、名前検索キーとして_10dataのインスタンスをname="katayama"で生成 keyObj = new search._10data(0,"katayama", null); //名前ソート、二分探索用のコンパレータのインスタンスを生成 search.NameComp nmComp = new search.NameComp(); //名前でソート Arrays.sort(x, nmComp); //二分探索で該当したインデックスを取得 index = Arrays.binarySearch(x, keyObj, nmComp); if (index > -1) { //該当したインデックスに紐付く情報を出力 System.out.println("名前検索の該当データ⇒" + x[index]); }else System.out.println("名前検索の該当無し"); } } /** * コンパレータ1/名前昇順 * コンパレータはComparatorを実装する。この時、扱う型をジェネリックスで指定する。 * compareの戻り値には、以下の単純な規約がある。 * 昇順ソート: * 引数1のソートキー < 引数2のソートキー⇒戻り値=-1 * 引数1のソートキー == 引数2のソートキー⇒戻り値=0 * 引数1のソートキー > 引数2のソートキー⇒戻り値=1 * 降順ソート:昇順の戻り値を符号反転すれば降順になる。 * ソートキーとなる名前=Stringクラスは、これらの戻り値を戻すcompareToメソッドが既に定義されているので、それを使う。 */ static class NameComp implements Comparator<search._10data> { public int compare(search._10data a, search._10data b) { return a.name.compareTo(b.name); } } /** * コンパレータ2/生徒番号昇順 */ static class NumberComp implements Comparator<search._10data> { public int compare(search._10data a, search._10data b) { return a.number - b.number; } } }

関連するQ&A