-1

以下の方法は仕事をしますが、あまり効率的ではありません。

これを行うためのよりエレガントなソリューションを知っている人はいますか?

私はこのようなことをいじりましたが、今のところ運がありません: /^(foo|bar|[[:space:][:punct:]])+$/

static public boolean matchTitle(String title, String title2) {

    Scanner scanner1 = new Scanner(title);
    Scanner scanner2 = new Scanner(title2);
    String searchTitle = title2;
    boolean match = false;
    int i = 0;
    while(i < 2){
        if(i == 1){
            scanner1 = new Scanner(title2);
            scanner2 = new Scanner(title);
            searchTitle = title;
        }

        // breaks into words
        while (scanner1.hasNext()){
            match = false;

            String token = scanner1.next();
            scanner2 = new Scanner(searchTitle);
            while (scanner2.hasNext() && !match){
                String token2 = scanner2.next();
                if(token.equals(token2)){
                    // if the words match
                    match = true;
                }
            }
            if(!match){ // we have a word that didn't match any words in the second title
                return false;
            }
        }
        i++;
    }
    return true;
}

("similar words here", "similar words here") // true

("ここに似た言葉", "ここに似た言葉") // true

("similar words here", "similar words here different") // false

4

2 に答える 2

3

私はより単純なバージョンに行きます:

List<String> words1 = Arrays.asList(title.split(" "));
List<String> words2 = Arrays.asList(title2.split(" "));

return words1.containsAll(words2) &&
       words2.containsAll(words1);

仮定:

  • title と title2 が null でない
  • 区切り文字はスペースのみ
  • 文字列に同じ単語が n 回含まれている場合、もう一方の文字列にもその単語が n 回含まれている必要があります

編集

あなたの編集は、重複が問題ないことを示しています。その場合、リストの代わりにセットを使用できます。

Set<String> words1 = new HashSet<String> (Arrays.asList(title.split(" ")));
Set<String> words2 = new HashSet<String> (Arrays.asList(title2.split(" ")));

return words1.size() == words2.size() && words1.containsAll(words2);

注:彼の回答で chm052 が示すように、セットの場合、順序を無視して等価性をチェックするだけです (ただし、リストの例にはありません)。

return words1.equals(words2);
于 2013-02-25T18:21:54.587 に答える
1

あなたが求めているのは、最初の文字列の単語のセットが 2 番目の文字列の単語のセットと等しいかどうかです。結局のところ、文字列について無視したいもの (単語の順序と単語の繰り返し) は、定義上、セットには存在しません。

だから、あなたが必要です

Set<String> words1 = new HashSet<String> (Arrays.asList(title.split(" ")));
Set<String> words2 = new HashSet<String> (Arrays.asList(title2.split(" ")));

return words1.equals(words2);

編集:

assyliasさんが指摘したように、sizeやcontainsAllメソッドからequalsメソッドに切り替えても機能的に大きな変化はありませんが、コードを読むとわかりやすいです。この方法でこのメソッドを set クラスと分離することも、おそらくより良い OO プラクティスです。たとえば、深い集合の等価性を検出するためのより優れたアルゴリズムが Java 集合クラスに実装されている場合、その改善を利用できるようになります。

ボーナス 2 番目の編集:

これに関するコメントスレッドで誰かが混乱している場合、それは assylias によるこの以前の回答に関するものです (そして、それがすべての場合に機能するかどうか):

List<String> words1 = Arrays.asList(title.split(" "));
List<String> words2 = Arrays.asList(title2.split(" "));
return words1.size() == words2.size() && words1.containsAll(words2);
于 2013-02-25T18:44:20.220 に答える