-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;
}

例子

("相似词在这里", "相似词在这里") // true

("相似的词在这里", "这里的词相似") // true

("这里相似词", "这里相似词不同") // 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 不为空
  • 空格是唯一的分隔符
  • 如果一个字符串包含 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 在他的回答中所指出的,在 Set 的情况下,您可以简单地检查是否相等,这会忽略顺序(但不在 List 示例中):

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

您要问的是第一个字符串中的单词集是否等于第二个字符串中的单词集。毕竟,根据定义,您想要忽略的关于字符串的内容(词序和重复词)并不存在于集合中。

所以,你需要

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 所指出的,如果您切换使用 equals 方法而不是 size 和 containsAll 方法,则功能没有太大变化,但是在阅读代码时更容易理解。以这种方式将此方法与 set 类解耦也可能是更好的 OO 实践;那么,例如,如果在 Java 集合类中实现了一种更好的算法来查找深度集合相等,那么您将可以使用该改进。

奖金第二次编辑:

如果有人对此评论线程感到困惑,那是关于 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 回答