現在、作成中のこのアプリケーションで奇妙な動作が発生しています。
序文
私が構築しているこのアプリケーションの目標は単純です。つまり、文字列のコレクションを取得し、複数のテキスト ファイルからそれらの各文字列を検索することです。アプリケーションは、各文字列の一意の一致も追跡します。つまり、文字列 "abcd" は、ファイル A に n 回出現する場合、1 回だけカウントされます。
このアプリケーションは主に多数のファイルと多数の文字列を処理するため、Runnable を実装するクラスを作成し、ExecutorService を使用して Runnable タスクを実行することにより、バックグラウンドで文字列検索を行うことにしました。また、文字列検索の速度を調べることにしたので、文字列一致のさまざまな方法 (つまり、Boyer-Moore アルゴリズム) を使用して時間の比較を開始しましString.contains()
たString.indexOf()
。http://algs4.cs.princeton.edu/53substring/BoyerMoore.java.htmlから Boyer-Moore アルゴリズムのソース コードを取得し、プロジェクトに含めました。ここから問題が始まりました...
問題
クラスを使用すると、文字列検索がさまざまな結果で返されることに気付きました (検索を実行するたびに、見つかった文字列の数は異なります) 。BoyerMoore
String.contains()
private boolean findStringInFile(String pattern, File file) {
boolean result = false;
BoyerMoore bm = new BoyerMoore(pattern); // This line still causes varying results.
try {
Scanner in = new Scanner(new FileReader(file));
while(in.hasNextLine() && !result) {
String line = in.nextLine();
result = line.contains(pattern);
}
in.close();
} catch (FileNotFoundException e) {
System.out.println("ERROR: " + e.getMessage());
System.exit(0);
}
return result;
}
上記のコードを使用しても、結果は一貫していませんでした。BoyerMoore
オブジェクトのインスタンス化によって結果が異なるようです。もう少し深く掘り下げたところ、BoyerMoore
コンストラクターの次のコードがこの矛盾を引き起こしていることがわかりました...
// position of rightmost occurrence of c in the pattern
right = new int[R];
for (int c = 0; c < R; c++)
right[c] = -1;
for (int j = 0; j < pat.length(); j++)
right[pat.charAt(j)] = j;
不一致の原因はわかりましたが、なぜそれが起こったのかはまだわかりません。マルチスレッドに関してはベテランではないので、可能な説明/洞察は大歓迎です!
以下は、検索タスクの完全なコードです...
private class Search implements Runnable {
private File mSearchableFile;
private ConcurrentHashMap<String,Integer> mTable;
public Search(File file,ConcurrentHashMap<String,Integer> table) {
mSearchableFile = file;
mTable = table;
}
@Override
public void run() {
Iterator<String> nodeItr = mTable.keySet().iterator();
while(nodeItr.hasNext()) {
String currentString = nodeItr.next();
if(findStringInFile(currentString , mSearchableFile)) {
Integer count = mTable.get(currentString) + 1;
mTable.put(currentString,count);
}
}
}
private boolean findStringInFile(String pattern, File file) {
boolean result = false;
// BoyerMoore bm = new BoyerMoore(pattern);
try {
Scanner in = new Scanner(new FileReader(file));
while(in.hasNextLine() && !result) {
String line = in.nextLine();
result = line.contains(pattern);
}
in.close();
} catch (FileNotFoundException e) {
System.out.println("ERROR: " + e.getMessage());
System.exit(0);
}
return result;
}
}