Как распознать две строки, когда большинство символов похожи

Я хочу получить true в этих примерах

"Hello Wolrld" == "HelloWorld"

Или

"hello world!!" == "helloworld"

Я знаю, что они не равны , но, поскольку большинство символов одинаковы, мне этого достаточно

Заранее спасибо

2
Mohammad Javad Noori 28 Фев 2018 в 09:40

4 ответа

Лучший ответ

Использовать это

Regex.Replace(textBox1.Text, @"[^0-9a-zA-Z]+", "").ToLower() == your string in lower case
2
Jophy job 28 Фев 2018 в 06:53

Вы можете вычислить расстояние Левенштейна двух строк (см., Например, это реализация C #) и затем определите порог, до которого вы считаете строки равными.

Какой разумный порог зависит от ваших требований. Вероятно, определение предиката как d <= a * Math.Min(string1.Length, string2.Length) должно сработать, где d - расстояние строк Левенштейна, а a - фактор "сходства" между 0 и 1. В ваших примерах {{ X3}} должно работать.

2
Kristof U. 28 Фев 2018 в 07:01

Это дает правдоподобие 80% похожих слов. Попробуйте это .

            String str1 = "Hello world";
            String str2 = "Helloworld!!";

            char[] charArray;

            int per = 0;
            int c = 0;
            if (str1.length() > str2.length()) {

                per = (str1.length() * 80) / 100; // 80% per match logic

                charArray = str1.toCharArray();

                for (int i = 0; i < str1.length(); i++) {

                    String chars = String.valueOf(charArray[i]);

                    if (str2.contains(chars)) {
                        c++;
                    }
                }
            } else {
                per = (str1.length() * 80) / 100; // 80% per match logic

                charArray = str2.toCharArray();

                for (int i = 0; i < str2.length(); i++) {

                    String chars = String.valueOf(charArray[i]);

                    if (str1.contains(chars)) {
                        c++;
                    }
                }
            }
            if (c >= per) {
                Toast.makeText(getApplicationContext(), "true", 0).show();
            } else {
                Toast.makeText(getApplicationContext(), "false", 0).show();
            }
0
SahdevRajput74 28 Фев 2018 в 07:16

Если вы ищете очень простую проверку, вы можете перечислить символы, используя Zip, чтобы сравнить их, посчитать совпадающие буквы и сообщить true, если количество совпадений превышает определенный порог. Это не захватит, если одна строка является сдвинутой версией другой; он будет ловить только общие буквы по одному и тому же индексу.

public static class ExtensionMethods
{
    public static bool FuzzyCompare(this string lhs, string rhs, float ratioRequired)
    {
        var matchingLetters =  lhs.Zip
            ( 
                rhs, 
                (a,b) => a == b ? 1 : 0
            )
            .Sum();
        return (float)matchingLetters / (float)lhs.Length > ratioRequired;
    }
}

Чтобы сравнить две строки, чтобы увидеть, совпадают ли они хотя бы на половине букв, передайте ratioRequired, равный 0,5.

    public static void Main()
    {

        var a = "ABCD";
        var b = "ABCDEFGHI";

        Console.WriteLine( a.FuzzyCompare(b, 0.5F) );
    }

Выход:

True

Код на DotNetFiddle

0
John Wu 28 Фев 2018 в 06:53