BohYoh.comトップページへ

Javaによるアルゴリズムとデータ構造

戻る  

演習3-5の解答

 2分探索アルゴリズムでは、探索すべきキー値と同じ値をもつ要素が複数存在する場合、それらの要素の先頭要素を見つけるとは限らない。たとえば、以下に示す配列から7を探索すると、中央要素のインデックスである5を見つけることになる。

 2分探索アルゴリズムによって探索に成功した場合、その位置から先頭側へ走査することによって、複数の要素が一致する場合でも、最も先頭側に位置する要素のインデックスを見つけられる。

 そのように改良したメソッドを作成せよ。
  static int binSearchX (int[] a , int n , int key )

// 演習3-5 // 2分探索(一致する先頭要素を見つける) import java.util.Scanner; class BinSearchX {     //--- 配列aの先頭n個の要素からkeyと一致する要素を2分探索 ---//     static int binSearchX(int[] a, int n, int key) {         int    pl = 0;        // 探索範囲先頭のインデックス         int    pr = n - 1;    //   〃  末尾のインデックス         do {             int    pc = (pl + pr2;    // 中央要素のインデックス             if (a[pc== key) {                 for ; pc > pl; pc--)    // keyと等しい先頭の要素を探す                     if (a[pc - 1< key)                         break;                 return pc;            // 探索成功             else if (a[pc< key)                 pl = pc + 1;        // 探索範囲を前半に絞り込む             else                 pr = pc - 1;        // 探索範囲を後半に絞り込む         while (pl <= pr);         return -1;                    // 探索失敗     }     public static void main(String[] args) {         Scanner stdIn = new Scanner(System.in);         System.out.print("要素数:");         int num = stdIn.nextInt();         int[] x = new int[num];        // 長さnumの配列         System.out.println("昇順に入力してください。");         System.out.print("x[0]:");        // 先頭要素の読込み         x[0= stdIn.nextInt();         for (int i = 1; i < num; i++) {             do {                 System.out.print("x[" + i + "]:");                 x[i= stdIn.nextInt();             while (x[i< x[i - 1]);    // 一つ前の要素より小さければ再入力         }         System.out.print("探す値:");        // キー値の読込み         int ky = stdIn.nextInt();         int idx = binSearchX(x, num, ky);    // 配列xから値がkyの要素を探索         if (idx == -1)             System.out.println("その値の要素は存在しません。");         else             System.out.println("その値は" "x[" + idx + "]にあります。");     } }


// 演習4-2 // int型両頭スタックの利用例(IntStackX2クラスの全メソッドを利用) import java.util.Scanner; class IntStackX2TesterEx {   public static void main(String[] args) {     Scanner stdIn = new Scanner(System.in);     IntStackX2 s = new IntStackX2(10);  // 最大10個プッシュできる両頭スタック     while (true) {       int menu, n, x = 0;       System.out.println("現在のデータ数:"+                  "A:" + s.size(IntStackX2.AorB.StackA                  "B:" + s.size(IntStackX2.AorB.StackB));       System.out.print("(1)Aにプッシュ (2)Aからポップ (3)Aからピーク " +                "(4)Aをダンプ (5)Aから探索 (6)Aを空にする\n" +                "(7)Bにプッシュ (8)Bからポップ (9)Bからピーク " +                "(10)Bをダンプ (11)Bから探索 (12)Bを空にする\n" +                "(13)情報表示 (0)終了:");       if ((menu = stdIn.nextInt()) == 0)         break;       switch (menu) {        case 1:                // Aにプッシュ         System.out.print("データ:");         x = stdIn.nextInt();         try {           s.push(IntStackX2.AorB.StackA, x);          catch (IntStackX2.OverflowIntStackX2Exception e) {           System.out.println("スタックが満杯です。");         }         break;        case 2:                 // Aからポップ         try {            x = s.pop(IntStackX2.AorB.StackA);           System.out.println("ポップしたデータは" + x + "です。");          catch (IntStackX2.EmptyIntStackX2Exception e) {           System.out.println("スタックが空です。");         }         break;        case 3:                 // Aからピーク         try {            x = s.peek(IntStackX2.AorB.StackA);           System.out.println("ピークしたデータは" + x + "です。");          catch (IntStackX2.EmptyIntStackX2Exception e) {           System.out.println("スタックが空です。");         }         break;        case 4:                 // Aをダンプ         s.dump(IntStackX2.AorB.StackA);         break;        case 5:                 // Aから探索         System.out.print("探索するデータ:");         x = stdIn.nextInt();         n = s.indexOf(IntStackX2.AorB.StackA, x);         if (n >= 0)           System.out.println("頂上から" (s.size(IntStackX2.AorB.StackA- n+"番目に存在します。");         else           System.out.println("そのデータはありません。");         break;        case 6:               // 空にする         s.clear(IntStackX2.AorB.StackA);         break;        case 7:                // Bにプッシュ         System.out.print("データ:");         x = stdIn.nextInt();         try {           s.push(IntStackX2.AorB.StackB, x);          catch (IntStackX2.OverflowIntStackX2Exception e) {           System.out.println("スタックが満杯です。");         }         break;        case 8:                 // Bからポップ         try {            x = s.pop(IntStackX2.AorB.StackB);           System.out.println("ポップしたデータは" + x + "です。");          catch (IntStackX2.EmptyIntStackX2Exception e) {           System.out.println("スタックが空です。");         }         break;        case 9:                 // Bからピーク         try {            x = s.peek(IntStackX2.AorB.StackB);           System.out.println("ピークしたデータは" + x + "です。");          catch (IntStackX2.EmptyIntStackX2Exception e) {           System.out.println("スタックが空です。");         }         break;        case 10:                 // Bをダンプ         s.dump(IntStackX2.AorB.StackB);         break;        case 11:                 // Bから探索         System.out.print("探索するデータ:");         x = stdIn.nextInt();         n = s.indexOf(IntStackX2.AorB.StackB, x);         if (n >= 0)           System.out.println("頂上から" (s.size(IntStackX2.AorB.StackB(s.capacity() - n1+"番目に存在します。");         else           System.out.println("そのデータはありません。");         break;        case 12:               // 空にする         s.clear(IntStackX2.AorB.StackB);         break;        case 13:               // 情報表示         System.out.println("容量:" + s.capacity());         System.out.println("Aのデータ数:" + s.size(IntStackX2.AorB.StackA));         System.out.println("Bのデータ数:" + s.size(IntStackX2.AorB.StackB));         System.out.println("Aは空" (s.isEmpty(IntStackX2.AorB.StackA)  "です。"                             "ではありません。"));         System.out.println("Bは空" (s.isEmpty(IntStackX2.AorB.StackB)  "です。"             "ではありません。"));         System.out.println("満杯" (s.isFull() "です。"                             "ではありません。"));         break;       }     }   } }


戻る