C# - 使用通配符比较两个字符串的最快方法

4
有没有比这个函数更快的方法来比较两个字符串(使用空格作为通配符)?
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。(需要比较的两个字符串长度相同)


你不需要像文件系统中的 * 通配符那样使用可变宽度通配符吗? - John Knoeller
目前我不需要这个功能,因为我总是使用此函数比较相同长度的字符串。 - Gregoire
7个回答

3
如果mask的长度小于word的长度,这个函数将在mask的末尾停止比较。在开头进行单词/掩码长度比较可以防止这种情况,并且可以快速消除一些明显的不匹配。

1
更重要的是,如果掩码比单词还长,当前的实现将会抛出一个异常。 - Anon.
谢谢您的建议。事实上,我总是比较相同长度的字符串,但我会添加检查,感谢。 - Gregoire

2

看起来这是一个相当不错的实现 - 我认为你不会比这更快了。

您是否对此代码进行了分析,并发现它是应用程序中的瓶颈?我认为这对于大多数情况来说应该是可以接受的。


2
循环非常简单,我不确定你能做得更好。你或许可以微调 if 语句中表达式的顺序。例如,由于短路效应,在 if 语句中按这种方式排序可能会更快:
 if (mask[index]!= word[index])) && (mask[index] != ' ')

假设匹配字符比匹配通配符更常见。当然,这只是理论,如果没有进行基准测试,我不会相信这会有所不同。正如其他人指出的那样,如果掩码和字符串的长度不相同,则该例程将失败。

谢谢您的回答。目前我有相同的几率获得通配符或字符。 - Gregoire

1

不确定这是否更快,但它看起来很整洁:

public static bool CustomCompare(this string word, string mask)
{
     return !mask.Where((c, index) => c != word[index] && c != ' ').Any();
}

1

变长比较: 我使用了您的代码作为自己应用程序的起点,该应用程序假定掩码长度短于或等于比较文本长度。这允许在掩码中有一个可变长度的通配符位置。例如:"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

如果你使用.而不是,你可以进行简单的正则表达式匹配。


1
一个正则表达式很可能会比较慢。 - Andrew Hare
2
正则表达式引擎可能会比这个稍微优化一些。而且你需要编写的代码也会更少,这是真正的优点。不过,就像任何“优化”一样,你需要进行基准测试——如果不值得进行基准测试,性能差异就无关紧要了。 - Anon.
更优化怎么做?即使正则表达式看起来像某种魔法咒语,但它们并不是神奇的。我真的怀疑更通用的正则表达式代码是否能比上面简单的循环更好。 - Kevin Gale
C#正则表达式在像这样简单的情况下明显较慢(是的,我已经为我的情况进行了基准测试),尽管如果您反复测试相同的通配符,则预编译表达式会有很大帮助。如果您有更复杂的模式或需要知道匹配字符串,或者如果这不是您的性能瓶颈,请选择Regex。 - Malcolm

0

我认为你没有给你的代码提供一点上下文,这有点不公平。当然,如果你只想搜索与模式长度相同的一个字符串,那么这是可以的。

然而,如果你将其用作模式匹配器的核心,其中还有其他几个模式需要查找,那么这是一种较差的方法。已知还有其他方法,最好的方法取决于你的确切应用。你关心的短语是“不精确模式匹配”。


谢谢你的建议。由于你要求上下文,我尝试生成密集的填字游戏(黑色方格不到8%),并且我正在寻找一种快速的方法来应用约束条件,以获取与列表中特定长度的模式匹配的所有单词或更多的300,000个单词。 - Gregoire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接