データベースにフレーズのリスト(フレーズは1つ以上の単語で構成されている場合があります)と入力文字列があります。これらのフレーズのどれが入力文字列に表示されるかを調べる必要があります。
Javaでそのようなマッチングを実行する効率的な方法はありますか?
簡単なハックは次のようになります。
find
すべてのフレーズが見つかるか、入力の終わりに達するまで繰り返し実行し、残りのフレーズのセットから一致を削除して検索しますそうすれば、入力したフレーズの数に関係なく、入力は1回だけトラバースされます。正規表現コンパイラが複数の選択肢に対して効率的なマッチャーを生成する場合、これにより適切なパフォーマンスが得られるはずです。ただし、これはフレーズと入力文字列、およびJava正規表現エンジンの品質に大きく依存します。
サンプルコード(テスト済みですが、パフォーマンスのために最適化またはプロファイルされていません):
public static boolean hasAllPhrasesInInput(List<String> phrases, String input) {
Set<String> phrasesToFind = new HashSet<String>();
StringBuilder sb = new StringBuilder();
for (String phrase : phrases) {
if (sb.length() > 0) {
sb.append('|');
}
sb.append(Pattern.quote(phrase));
phrasesToFind.add(phrase.toLowerCase());
}
Pattern pattern = Pattern.compile(sb.toString(), Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
phrasesToFind.remove(matcher.group().toLowerCase());
if (phrasesToFind.isEmpty()) {
return true;
}
}
return false;
}
いくつかの警告:
Pattern.UNICODE_CASE
を追加して呼び出す必要があります。toLowerCase(Locale)
toLowerCase()
Locale
これがjavaを使用した解決策です。使用する文字列について何も指定していないので、一般的な例を検討します
Pattern p = Pattern.compile("cat");
// Create a matcher with an input string
Matcher m = p.matcher("one cat," +" two cats in the yard");
boolean b = m.matches(); // Should return true
お役に立てば幸い
参照: http: //java.sun.com/developer/technicalArticles/releases/1.4regex/
sql = "SELECT phrase " +
" FROM phrases " +
" WHERE phrase LIKE $1";
PreparedStatement pstmt = conn.prepareStatement (sql);
// probably repeated, if more than one input:
pstmt.setString (1, "%" + input + "%");
ResultSet rs = pstmt.executeQuery ();
プリペアドステートメントはデータベースに適合するようにチェックされ、繰り返し呼び出される場合は高速であるため、複数の入力がある場合でも、ループで実行される高速である必要があります。
もちろん、すべてのフレーズをRAMやマップにロードすることもできます。準備が遅いので、1つの入力だけでなく、複数の呼び出しがある場合は速くなる可能性があります。しかし、データベースは検索に非常に効率的であることがよくあります。
データベースの検索フレーズを、一般的な始まりに基づいてツリーに整理できます。そのツリーのノードに一致させようとしている文字ごとに文字列を分析することができます。