如何计算C#中两个字符串之间的相似度?

时间:2012-03-11 17:41:22

标签: c# .net string similarity

我希望评估两个字符串之间的相似性(包括大小写),并给出介于0和1之间的值。

我尝试了Levenshtein距离实现,但它只给出了整数,并没有比较内部字母。

例如比较“ABCD”和“Abcd”给出距离3,“AOOO”也给出距离3,但显然“Abcd”比“AOOO”更好地匹配。

因此,与“ABCD”相比,我希望“ABcd”与“Abcd”最相似,然后是“AOOO”,然后是“AOOOO”

我也看了here,但我不是在寻找可变长度算法。

由于

3 个答案:

答案 0 :(得分:5)

尝试这样的事情

double d = (LevenshteinDist(s, t) + LevenshteinDist(s.ToLower(), t.ToLower())) /
           2.0 * Math.Max(s.Length, t.Length);

如果您希望对案例差异的重视程度低于字母差异,则可以对术语

赋予不同的权重
double d = (0.15*LevenshteinDist(s, t) + 
            0.35*LevenshteinDist(s.ToLower(), t.ToLower())) /
           Math.Max(s.Length, t.Length);

请注意,权重总计为0.5,因此将除法分为2.0过时。

答案 1 :(得分:2)

    bool check(string[] a, string s)
    {
        for (int i = 0; i < a.Length; i++)
            if (s == a[i])
                return true;
        return false;
    }

    public double simi(string string1, string string2)
    {
        int sub1 = 0;
        int sub2 = 0;
        string[] sp1 = new string[string1.Length - 1];
        string[] sp2 = new string[string2.Length - 1];
        string[] sp3 = new string[string1.Length - 1];
        string[] sp4 = new string[string2.Length - 1];
        for (int i = 0; i < string1.Length - 1; i++)
        {
            string x = "";
            x = string1.Substring(i, 2);

            sp1[sub1] = x;
            ++sub1;
        }
        for (int i = 0; i < string2.Length - 1; i++)
        {
            string x = "";
            x = string2.Substring(i, 2);
            sp2[sub2] = x;
            ++sub2;
        }


        int j = 0, k = 0;

        for (int i = 0; i < sp1.Length; i++)
            if (check(sp3, sp1[i]) == true)
            {

                continue;
            }
            else
            {
                sp3[j] = sp1[i];
                j++;

            }

        for (int i = 0; i < sp2.Length; i++)
            if (check(sp4, sp2[i]) == true)
            {

                continue;
            }
            else
            {
                sp4[k] = sp2[i];
                k++;


            }

        Array.Resize(ref sp3, j);
        Array.Resize(ref sp4, k);

        Array.Sort<string>(sp3);
        Array.Sort<string>(sp4);

        int n = 0;


        for (int i = 0; i < sp3.Length; i++)
        {

            if (check(sp4, sp3[i]))
            {

                n++;
            }


        }

        double resulte;

        int l1 = sp3.Length;
        int l2 = sp4.Length;

        resulte = ((2.0 * Convert.ToDouble(n)) / Convert.ToDouble(l1 + l2)) * 100;

        return resulte;
    }

答案 2 :(得分:1)

使用自定义表T调整Levenshtein距离。设置插入成本= 1.删除成本也是1.设T(c,d)表示用d替换c的惩罚。 T(c,c)应为= 0.T(c,d)应<= 2。

定义Max(n,m)是长度为n和m的字符串的最大理论距离。显然,Max(n,m)= n + m。

定义距离(s,t)是将s改为t除以Max(s,t)的成本。你去吧。

小心定义T,使定义服从距离公理:

  • 距离(s,s)= 0
  • 距离(s,t)=距离(t,s)
  • 距离(s,t)&lt; =距离(s,u)+距离(u,t)

然后在更多情况下会更有用。