6

こんにちは仲間のプログラマー、

文字列のニアマッチに関して、助けを求めたいと思います。

現在、説明の文字列を保存するプログラムがあります。ユーザーは、説明の全部または一部を入力して説明を検索できます。

ほぼ一致する検索を実装したいと思います。たとえば、実際の説明は「hello world」ですが、ユーザーが誤って「helloeorld」という検索を入力しました。プログラムは、ユーザーに「helloworld」を返すことができる必要があります。

パターンと一致を調べて実装しようとしましたが、文字列と一致するために正規表現が必要であるため、説明に規則的なパターンがありません。string.containsも試しましたが、どちらも機能しないようです。以下は私が実装しようとしたコードの一部です。

    ArrayList <String> list = new ArrayList<String>();
    list.add("hello world");
    list.add("go jogging at london");
    list.add("go fly kite");
    Scanner scan = new Scanner(System.in);

    for(int i = 0; i < list.size(); i++){
      if(list.get(i).contains(scan.next())) {
         System.out.println(list.get(i));
      }
    }

仲間のプログラマーがこれを手伝ってくれませんか?

4

3 に答える 3

3

レーベンシュタイン距離は、2つの弦の違いを限定することができます

これがここからの実装です

public class LevenshteinDistance {
   private static int minimum(int a, int b, int c) {
      return Math.min(Math.min(a, b), c);
   }

   public static int computeLevenshteinDistance(
      CharSequence str1,
      CharSequence str2 )
   {
      int[][] distance = new int[str1.length() + 1][str2.length() + 1];

      for (int i = 0; i <= str1.length(); i++)
         distance[i][0] = i;
      for (int j = 1; j <= str2.length(); j++)
         distance[0][j] = j;

      for (int i = 1; i <= str1.length(); i++)
         for (int j = 1; j <= str2.length(); j++)
            distance[i][j] =
               minimum(
                  distance[i - 1][j] + 1,
                  distance[i][j - 1] + 1,
                  distance[i - 1][j - 1] +
                     ((str1.charAt(i - 1) == str2.charAt(j - 1)) ? 0 : 1));

      return distance[str1.length()][str2.length()];
   }
}
于 2012-11-02T14:26:16.830 に答える
2

LCS(最長共通部分列)を使用できます。http: //en.wikipedia.org/wiki/Longest_common_subsequence_problemを参照してください。

public class LCS {

    public static void main(String[] args) {
        String x = StdIn.readString();
        String y = StdIn.readString();
        int M = x.length();
        int N = y.length();

        // opt[i][j] = length of LCS of x[i..M] and y[j..N]
        int[][] opt = new int[M+1][N+1];

        // compute length of LCS and all subproblems via dynamic programming
        for (int i = M-1; i >= 0; i--) {
            for (int j = N-1; j >= 0; j--) {
                if (x.charAt(i) == y.charAt(j))
                    opt[i][j] = opt[i+1][j+1] + 1;
                else 
                    opt[i][j] = Math.max(opt[i+1][j], opt[i][j+1]);
            }
        }

        // recover LCS itself and print it to standard output
        int i = 0, j = 0;
        while(i < M && j < N) {
            if (x.charAt(i) == y.charAt(j)) {
                System.out.print(x.charAt(i));
                i++;
                j++;
            }
            else if (opt[i+1][j] >= opt[i][j+1]) i++;
            else                                 j++;
        }
        System.out.println();

    }

}

他の解決策は、Aho–Corasick文字列マッチングアルゴリズムです 。これを参照してください: 文字列内の部分文字列を検索するための高速アルゴリズム

于 2012-11-02T14:20:04.197 に答える
2

レーベンシュタイン距離は、この問題に役立つ可能性があります。Apache CommonsLangStringUtilsにはその実装があります。
また、difference文字列の違いを知りたい場合は、StringUtilsのメソッドが興味深いかもしれません。

于 2012-11-02T14:25:50.997 に答える