【问题标题】:C# - fastest way to compare two strings using wildcardsC# - 使用通配符比较两个字符串的最快方法
【发布时间】:2010-02-11 01:17:48
【问题描述】:

有没有比这个函数更快的方法来比较两个字符串(使用空格作为通配符)?

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。 (被比较的两个需要相同的长度)

【问题讨论】:

  • 所以你不需要像文件系统 * 通配符这样的可变宽度通配符?
  • 目前我不需要它,因为我总是用这个函数比较相同长度的字符串

标签: c# string comparison


【解决方案1】:

如果 mask.length 小于 word.length,此函数将在 mask 末尾停止比较。一开始的单词/掩码长度比较可以防止这种情况发生,也可以快速消除一些明显的不匹配。

【讨论】:

  • 稍微更重要的是,如果掩码比单词长,当前的实现会抛出异常。
  • 感谢您的建议。事实上,我总是比较相同长度的字符串,但我会添加检查,谢谢。
【解决方案2】:

循环非常简单,我不确定你能做得更好。您也许可以对 if 语句中的表达式顺序进行微优化。例如,由于 && 的短路,以这种方式订购 if 语句可能会更快

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

假设匹配字符比匹配通配符更常见。当然,这只是理论,如果不进行基准测试,我不会相信它会有所作为。

正如其他人指出的那样,如果掩码和字符串的长度不同,则例程会失败。

【讨论】:

  • 感谢您的回答。目前,我拥有通​​配符或字符的几率相同。
【解决方案3】:

这看起来是一个很好的实现——我认为你不会比这更快。

您是否已分析此代码并发现它是您应用程序的瓶颈?我认为这对于大多数用途来说应该没问题。

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 正则表达式很可能会更慢。
    • 正则表达式引擎可能会比这稍微优化一些。您自己编写的代码也更少,这是真正的优势。尽管与任何“优化”一样,您需要对其进行基准测试 - 如果不值得进行基准测试,则性能差异并不重要。
    • 如何更优化?正则表达式并不神奇,即使它们看起来确实像一些魔法咒语。我真的怀疑更通用的正则表达式代码能比上面的简单循环做得更好。
    • c# Regex 对于像这样的简单案例来说要慢得多(是的,我已经针对我的案例对其进行了基准测试),尽管如果您重复测试同一个通配符,预编译表达式会有很大帮助。如果您有更复杂的模式或需要知道匹配字符串,或者这不是您的性能瓶颈,请使用 Regex。
    【解决方案5】:

    变长比较: 我将您的代码用作我自己的应用程序的起点,该应用程序假定掩码长度小于或等于比较文本长度。允许在掩码中使用可变长度的通配符点。即:“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;
        } 
    

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

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

        但是,如果您将其用作模式匹配器的核心,并且您将要寻找其他几种模式,那么这是一种糟糕的方法。还有其他已知方法,其中最好的方法取决于您的具体应用。短语“不精确模式匹配”是您关心的短语。

        【讨论】:

        • 感谢您的提示。当您询问上下文时,我尝试生成密集的填字游戏(少于 8% 的黑色案例),并且我搜索应用约束的快速方法来获取与列表中的模式匹配的所有单词(具有特定长度)或多或少 300000 字。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-06
        • 1970-01-01
        • 2012-03-15
        • 1970-01-01
        相关资源
        最近更新 更多