【问题标题】:Fast multiple string compare快速多字符串比较
【发布时间】:2013-08-22 14:07:36
【问题描述】:

在 c# 中是否有一种快速的方法可以用更高效的代码替换以下代码:

string letters = "a,b,c,d,e,f";

if (letters.Contains("a"))
{
    return true;
}

if (letters.Contains("b"))
{
    return true;
}

if (letters.Contains("c"))
{
    return true;
}

我想消除必须具有三行比较代码的情况。

谢谢!

【问题讨论】:

  • 这里使用 linq 是一个例子stackoverflow.com/questions/194930/…
  • 您的用例是什么?你从哪里得到字母或输入?
  • return letters.Contains("a") || letters.Contains("b") || letters.Contains("c")?
  • 还有为什么你的测试字符串中有,逗号......?
  • 除了下面的所有答案(都很好),我建议您创建一个扩展方法或可重用的静态方法来为您完成工作并隐藏实现细节。没有什么比您的 自己的 自定义签名更好的了,例如 letters.HasAny("abc")letters.HasAny('a', 'b', 'c'),或者如果“abc”检查很常见,letters.HasABC()(或任何对您最有意义的名称/签名)。在内部,该扩展方法实现可以使用以下任何想法,针对速度或维护或灵活性进行优化,或者你有什么。

标签: c# string linq


【解决方案1】:

你可以这样使用:

return letters.Any(c => c == 'a' || c == 'b' || c == 'c');

或者这个:

var lettersToLookFor = "abc";
return letters.Any(c => lettersToLookFor.Contains(c));

根据 cmets,前一个代码块的最后一行可以进一步缩短:

return letters.Any(lettersToLookFor.Contains);

【讨论】:

  • 甚至:letters.Any(lettersToLookFor.Contains).
【解决方案2】:

如果您实际上是在寻找字符串中的单个字符,您可以使用 IndexOfAny

return letters.IndexOfAny('a', 'b', 'c') >= 0;

它对整个字符串进行一次传递,并将字符串中的每个字符与传入的字符进行比较。

如果不存在任何字符,则仍然是 M * N 比较(与上面的 3 个 if 相同),但如果确实存在任何字符,它会更快地脱离闪避。
此外,对于较长的字符串,它对 CPU 缓存内存更友好。

【讨论】:

    【解决方案3】:

    您可以使用Intersect 来查看两个字符集之间是否有任何共同字符。请注意,字符串实现了IEnumerable<char>,因此您可以将所有字符串视为字符序列。

    bool result = "abc".Intersect(letters).Any();
    

    请注意,此解决方案会将letters 中的所有字符放入HashSet,因此将比当前发布的其他解决方案高效得多,这些解决方案对字符串执行多个线性搜索,假设字符串是一个非平凡的大小,并且搜索字符不在开始附近。 (你确实说过效率很重要。)

    【讨论】:

    • “显着提高效率”:这完全取决于实际的字符串。
    【解决方案4】:

    最简单的解决方案是club three if in single statement,或者可以使用Any(),如提到的Daniel

    if (letters.Contains("a") || letters.Contains("b") || letters.Contains("c"))
    {
        return true;
    }
    

    【讨论】:

      【解决方案5】:

      LINQ 是要走的路。

      return letters.Any(c => c == 'a' || c == 'b' || c == 'c');
      

      【讨论】:

      • 大坝,丹尼尔领先我一分钟
      【解决方案6】:
      var arr = new []{"a","b","c"};
      letters.Any(m => arr.Contains(m))
      

      【讨论】:

        【解决方案7】:

        使用String.IndexOfAny(Char[])之类的方法怎么样?

        string letters = "a,b,c,d,e,f";
        
        if ((letters.IndexOfAny(new char[] { 'a', 'b', 'c' }) >= 0))
        {
           return true;
        }
        

        此实例中第一次出现的从零开始的索引位置 在 anyOf 中找到任何字符的地方; -1 如果 anyOf 中没有字符 找到了。

        【讨论】:

        • >= 0,而不是 > 0。-1 是失败
        【解决方案8】:

        您可以使用正则表达式,但我无法保证效率,您必须运行比较并获取时间:

        return Regex.IsMatch(letters, "[abc]");
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-12
          • 2013-05-06
          相关资源
          最近更新 更多