Как я могу вычислить сходство между двумя строками в C #? - PullRequest
0 голосов
/ 11 марта 2012

Я хочу оценить сходство (включая регистр) между двумя строками и дать значение между 0 и 1.

Я пробовал реализацию расстояния Левенштейна, но она дает только целые числа и не сравнивает внутренние алфавиты.

Например, сравнение "ABCD" и "Abcd" дает расстояние 3, а "AOOO" также дает расстояние 3, но ясно, что "Abcd" лучше соответствует, чем "AOOO".

Таким образом, по сравнению с «ABCD» я хочу, чтобы «ABcd» был наиболее похожим, чем «Abcd», затем «AOOO», затем «AOOOO»

Я также посмотрел здесь , но я не ищу алгоритм переменной длины.

Спасибо

Ответы [ 3 ]

5 голосов
/ 11 марта 2012

Попробуйте что-то вроде этого

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 устаревших.

2 голосов
/ 29 марта 2016
    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;
    }
1 голос
/ 11 марта 2012

Адаптируйте расстояние Левенштейна с помощью пользовательской таблицы T. Пусть стоимость вставки = 1. Стоимость удаления также 1. Пусть T (c, d) обозначает штраф за замену c на d. T (c, c) должно быть = 0. T (c, d) должно быть <= 2. </p>

Определите Max (n, m) как максимальное теоретическое расстояние строк длиной n и m. Очевидно, Max (n, m) = n + m.

Define Distance (s, t) - стоимость изменения s до t, деленная на Max (s, t). Вот, пожалуйста.

Будьте внимательны при определении T, чтобы определение соответствовало аксиомам расстояния:

  • Расстояние (с, с) = 0
  • Расстояние (с, т) = Расстояние (т, с)
  • Расстояние (s, t) <= Расстояние (s, u) + Расстояние (u, t) </li>

Тогда это будет более полезно в большем количестве ситуаций.

...