Сравнение списка строк друг с другом оптимально

1

Я хочу сравнить список строк друг с другом с помощью Damerau до Levenshtein Distance

В настоящее время у меня есть:

char lastchar = (char)('z'+1);

        SimilarStrings similarStrings = new SimilarStrings();

        List<String> listString = new List<string>();

        listString.Add("Rammstein");
        listString.Add("Ramstein");
        listString.Add("Rammsten");

        listString.Add("Metallica");
        listString.Add("Metalica");
        listString.Add("Metaica");

        for (int i = 0; i < listString.Count(); i++)
        {
            for(int n = 0; n < listString.Count(); n++)
            {
                String str1 = String.Copy(listString[i]);
                String str2 = String.Copy(listString[n]);
                Console.Write(str1); Console.Write(" to "); Console.Write(str2 + "\n");
                int DADistance = SimilarStrings.damerauLevenshteinDistance(str1, str2, (int)lastchar);
                Console.WriteLine(DADistance);
            }
        }

Это прекрасно работает, единственная проблема заключается в том, что каждое сравнение выполняется дважды. Это означает, что "Rammstein" сравнивается с "Metallica", а затем "Metallica" снова сравнивается с "Rammstein". Половины сравнения было бы достаточно. Но как мне это сделать в хорошей форме? Я могу только подумать о некоторых сложных способах.

Теги:

2 ответа

4
Лучший ответ

Стандартный способ - запустить внутренний цикл из индекса внешнего цикла плюс один.

for (int i = 0; i < listString.Count(); i++)
    for (int n = i + 1; n < listString.Count(); n++)

Это предполагает, что вы не хотите сравнивать каждую строку с самим собой - если вы это сделаете, удалите + 1.

Вот пример логики. Если ваш список был: abcd, вы бы хотели сравнить a с:

a <> b
a <> c
a <> d

Для b вам не нужно сравнивать b с a, потому что вы уже сравнили a со всем. Итак, вы можете начать с c:

b <> c
b <> d

И для c вы уже сравнили a и b со всем, поэтому вы можете начать с d:

c <> d

Поэтому каждый элемент нужно сравнить только с элементами после него в списке - это то, что выражается вложенными циклами выше.

1

Это должно предотвратить дублирование сравнений

    for (int i = 0; i < listString.Count(); i++)
    {
        for(int n = i + 1; n < listString.Count(); n++)
        {
            ...
        }
    }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню