web-dev-qa-db-ja.com

文字列の配列に対するバイナリ検索の実装

私はこれに少し問題があります。入力配列はファイル入力に基づいており、配列のサイズはファイルの最初の行で指定されます。 binarySearchメソッドは問題ないように見えますが、機能していないようです。誰でも助けることができますか?ありがとう。

public static int binarySearch(String[] a, String x) {
    int low = 0;
    int high = a.length - 1;
    int mid;

    while (low <= high) {
        mid = (low + high) / 2;

        if (a[mid].compareTo(x) < 0) {
            low = mid + 1;
        } else if (a[mid].compareTo(x) > 0) {
            high = mid - 1;
        } else {
            return mid;
        }
    }

    return -1;
}

public static void main(String[] args) {

    Scanner input = new Scanner(System.in);

    System.out.println("Enter the name of your file (including file extension): ");
    String filename = input.next();

    String[] numArray;
    try (Scanner in = new Scanner(new File(filename))) {
        int count = in.nextInt();

        numArray = new String[count];

        for (int i = 0; in.hasNextInt() && count != -1 && i < count; i++) {
            numArray[i] = in.nextLine();
        }

        for (int i = 0; i < count; i++) //printing all the elements
        {
            System.out.println(numArray[i]);
        }

        String searchItem = "The";

        System.out.println("The position of the String is:");
        binarySearch(numArray, searchItem);

    } catch (final FileNotFoundException e) {
        System.out.println("That file was not found. Program terminating...");
        e.printStackTrace();

    }

}
4
user5274758

参考までに、次の例を追加しました。

import Java.util.Arrays;

public class BinaryStringSearch {

    public static void main(String[] args) {

        String array[] ={"EWRSFSFSFSB","BB","AA","SDFSFJ","WRTG","FF","ERF","FED","TGH"};
        String search = "BB";

        Arrays.sort(array);

        int searchIndex = binarySearch(array,search);

        System.out.println(searchIndex != -1 ? array[searchIndex]+ " - Index is "+searchIndex : "Not found");
    }

    public static int binarySearch(String[] a, String x) {
        int low = 0;
        int high = a.length - 1;
        int mid;

        while (low <= high) {
            mid = (low + high) / 2;

            if (a[mid].compareTo(x) < 0) {
                low = mid + 1;
            } else if (a[mid].compareTo(x) > 0) {
                high = mid - 1;
            } else {
                return mid;
            }
        }

        return -1;
    }

}
7

私はそれが役立つことを願っています:

 public static void main(String ar[]){

    String str[] = {"account","angel","Apple","application","black"};
    String search= "application";
    int length = str.length-1;
    BinarySearchInString findStrin = new BinarySearchInString();
    int i = findStrin.find(str, 0, length, search);
    System.out.println(i);
}

  public int find(String first[], int start, int end, String searchString){
    int mid = start + (end-start)/2;

    if(first[mid].compareTo(searchString)==0){
        return mid;
    }
    if(first[mid].compareTo(searchString)> 0){
        return find(first, start, mid-1, searchString);
    }else if(first[mid].compareTo(searchString)< 0){
        return find(first, mid+1, end, searchString);
    }
    return -1;
  }
1
vaibhav

すでに述べた結果の欠落した印刷に加えて、私が見つけることができる4つの問題があります。

1:numArrayという名前の_String[]_があり、Stringを検索しています。_"The"_名前numArrayは少し誤解を招く可能性があります。

2:ファイル内のStringの数が、ファイル内の最初のトークンとしてintegerによって指定されている、ある種の指定された入力ファイル形式があると仮定します。ただし、これは、numArrayにデータを入力するforループの条件として、in.hasNextInt()があり、次のトークンはin.nextLine()in.hasNext()in.next()などの補完的なチェック/削除メソッドを使用する必要があります。 Scanner[〜#〜] api [〜#〜] を確認してください。

3:binarySearch(String[], String)メソッドはString.compareTo(String)を使用します。これは、このStringのパラメーターStringへの辞書式順序を決定します。大文字と小文字を比較しようとすると、"the".compareTo("The")が_0_にならないため、期待どおりの結果が得られない場合があります。 String[〜#〜] api [〜#〜] をチェックして、ファイルの読み取り中にすべての入力を1つのケースに強制するか、またはを使用するオプションを確認する必要があります。メソッドとの比較の異なるフレーバー。

4:最後に表示されるのは、ちょっとしたコーナーケースと見なされるかもしれませんが、String配列が十分に大きく、検索文字列が右側にある可能性があります。高インデックス側、配列のArrayIndexOutOfBoundsExceptionを取得する場合があります。これは、結果が_(low + high)_より大きい場合、_Integer.MAX_VALUE_が負の値になる可能性があるためです。次に、結果を2で割っても、負の値が得られます。これは、2で割る代わりに結果をビットシフトすることで解決できます_(low + high) >>> 1_。 Joshua Blochは、分割統治アルゴリズムのこの一般的な欠陥について素晴らしい 記事 を持っています。

0
bombe

あなたの問題は、結果を出力するのを忘れたことだと思います。 binarySearch(numArray, searchItem);System.out.println(binarySearch(numArray, searchItem));に置き換えてみてください

0
Mike Rylander

@Mike Rylanderが見つけたように、結果を出力するのを忘れていました。

Arrays.binarySearch 独自の実装の代わりに。

(原則として、JREライブラリは十分にテストされ、十分に文書化されており、高速です。「Javaバイナリ検索」をグーグルで検索したところ、この質問はランク付けされています。@ Thusitha Indunilのコードを試してみましたが、仕事。もっとググってみたらArrays.binarySearch、うまくいきました。)

0