我如何在java中找到两个相似的字符串?

时间:2013-12-30 18:29:42

标签: java string compare

我希望找到以相互比较字符串的方式,它理解在以下示例中s1和s2之间没有区别。

String s1 = "John: would you please one the door";
String s2 = "John: would you please one the door  ????";

我该怎么办?

4 个答案:

答案 0 :(得分:5)

使用String metric描述字符串之间的相似性概念。字符串度量的基本示例是Levenshtein distance(通常称为编辑距离)。

Wikibooks提供了此算法的Java实现:http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#Java

答案 1 :(得分:1)

我不知道有什么好的技巧。但摆脱多个空间和交互可能是一个开始。

String s1, s2;

s1 = s1.replaceAll(" {2,}", " ").replaceAll("[.?!/\\()]", "").trim();
s2 = s2.replaceAll(" {2,}", " ").replaceAll("[.?!/\\()]", "").trim();

if (s1.equalsIgnoreCase(s1))
{

}

适用于您的字符串演示的演示:http://ideone.com/FSHOJt

答案 2 :(得分:1)

类似地暗示存在共性。这是一个非常重要的问题。您真正要求的是相关性分数和Faceted search。这通常通过将字符串标记为其基本单词并检查结果中是否存在公共基本单词来完成。作为一个具体的例子,请使用句子:

“阴暗的身影落在他们身上。”

你可以将其分解为各个方面:

shadow
figure
fell

每个都可以用同义词进行评估:

shadow -> dark, shade, silhouette,  etc...
figure -> statistic, number, quantity, amount, level, total, sum, silhouette, outline, shape, form, etc...
fell -> cut down, chop down, hack down, saw down, knock down/over, knock to the ground, strike down, bring down, bring to the ground, prostrate,  etc...

然后对比较字符串进行相同的操作,并计算共同的面。更常见的方面是比赛的相关性越高。

在开源社区中有许多相当重量级的工具,如LuceneSolr来解决这个问题,但是你可以通过将字符串分解为标记来简单地完成一个简单的版本寻找共同的代币。一个简单的例子:

public class TokenExample {

    public static HashMap<String, Integer> tokenizeString(String s)
    {
        // process s1 into tokens
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        for (String token : s.split("\\s+"))
        {
            // normalize the token
            token = token.toLowerCase();
            if ( map.containsKey(token) )
            {
                map.put(token, map.get(token)+1);
            }
            else
            {
                map.put(token, 1);
            }
        }
        return map;
    }

    public static Integer getCommonalityCount(String s1, String s2)
    {
        HashMap<String, Integer> map1 = tokenizeString(s1);
        HashMap<String, Integer> map2 = tokenizeString(s2);

        Integer commonIndex = 0;
        for (String token : map1.keySet())
        {
            if ( map2.containsKey(token))
            {
                commonIndex += 1;
                // you could instead count for how often they match like this
                // commonIndex += map2.get(token) + map1.get(token);
            }
        }
        return commonIndex;
    }

    public static void main(String[] args) {
        String s1 = "John: would you please one the door";
        String s2= "John: would you please one the door  ????";

        String s3 = "John: get to the door and open it please ????";
        String s4= "John: would you please one the door  ????";

        System.out.println("Commonality index: " + getCommonalityCount(s1, s2));
        System.out.println("Commonality index: " + getCommonalityCount(s3, s4));
    }
}

答案 3 :(得分:-1)

这个问题有各种方法,并且使用Levenshtein距离来解决这个问题的简便方法。 另一种方法是余弦相似性。 您需要更多详细信息,请发表评论。