C # - самый быстрый способ сравнить две строки с использованием подстановочных знаков - PullRequest
4 голосов
/ 11 февраля 2010

Есть ли самый быстрый способ сравнить две строки (используя пробел для подстановочного знака), чем эта функция?

public static bool CustomCompare(this string word, string mask)
{

    for (int index = 0; index < mask.Length; index++)
    {
        if (mask[index] != ' ') && (mask[index]!= word[index]))
        {
            return false;
        }
    }
    return true;
}

Пример: «S nt nce» по сравнению с «Sentence» вернет true. (Сравниваемые два должны иметь одинаковую длину)

Ответы [ 7 ]

3 голосов
/ 11 февраля 2010

Если mask.length меньше word.length, эта функция прекратит сравнение в конце маски. Сравнение длины слова / маски в начале могло бы предотвратить это, а также быстро устранить некоторые очевидные несоответствия.

2 голосов
/ 11 февраля 2010

Цикл довольно прост, и я не уверен, что вы можете сделать намного лучше. Возможно, вы сможете микрооптимизировать порядок выражения в операторе if. Например, из-за короткого замыкания символа && может быть быстрее упорядочить оператор if таким образом

 if (mask[index]!= word[index])) && (mask[index] != ' ')

Предполагая, что совпадающие символы встречаются чаще, чем совпадающие символы подстановки. Конечно, это всего лишь теория, и я бы не поверил, что она имела значение, если не сравнивать ее.

И как уже отмечали другие, процедура не выполняется, если маска и строка имеют разную длину.

2 голосов
/ 11 февраля 2010

Это похоже на довольно хорошую реализацию - я не думаю, что вы получите намного быстрее, чем это.

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

1 голос
/ 28 февраля 2012

Не уверен, что это быстрее, но выглядит аккуратно:

public static bool CustomCompare(this string word, string mask)
{
     return !mask.Where((c, index) => c != word[index] && c != ' ').Any();
}
1 голос
/ 28 декабря 2011

Сравнение переменной длины: Я использовал ваш код в качестве отправной точки для своего собственного приложения, в котором предполагается, что длина маски меньше или равна длине текста сравнения. с учетом подстановочного знака переменной длины в маске. то есть: "concat" будет соответствовать маске "c ncat" или "c t" или даже "c nc t"

    private bool CustomCompare(string word, string mask)
    {
        int lengthDifference = word.Length - mask.Length;
        int wordOffset = 0;
        for (int index = 0; index < mask.Length; index++)
        {
            if ((mask[index] != ' ') && (mask[index]!= word[index+wordOffset]))                
            {
                if (lengthDifference <= 0)
                {
                    return false;
                }
                else
                {
                    lengthDifference += -1;
                    wordOffset += 1;
                }
            }
        }
        return true;
    } 
1 голос
/ 11 февраля 2010

Если бы вы использовали . вместо , вы могли бы сделать простое совпадение с регулярным выражением.

0 голосов
/ 11 февраля 2010

Я думаю, что вы делаете небольшую несправедливость, не давая немного контекста вашему коду. Конечно, если вы хотите искать только одну строку символов той же длины, что и ваш шаблон, то да, это нормально.

Однако, если вы используете это как сердце для сопоставления с образцом, где есть несколько других образцов, которые вы будете искать, это плохой метод. Существуют и другие известные методы, лучший из которых зависит от вашего конкретного применения. Фраза «неточное сопоставление с образцом» - это фраза, которая вас интересует.

...