【问题标题】:What algorithm .Net use for searching a pattern in a string?.Net 使用什么算法搜索字符串中的模式?
【发布时间】:2010-04-06 10:43:07
【问题描述】:

我现在正在研究字符串搜索算法,想知道什么算法用于 .NET String.Contains 函数。 Reflector 显示使用了这个函数,但我不知道它的名字是什么意思。

private static extern int InternalFindNLSStringEx(IntPtr handle, string localeName, int flags, string source, int sourceCount, int startIndex, string target, int targetCount);

【问题讨论】:

标签: c# .net algorithm


【解决方案1】:

这只是简单的字符串搜索实现,通过文本和模式的嵌套循环,运行时间为 O(n·m)。

特别是,MSDN 没有指定此方法的性能,因此假设更好的性能是不安全的。

此外,大多数高级模式搜索方法都非常专门用于某些字符串类型,虽然更好的通用搜索算法,但在 String.IndexOf 中实现一个在某种程度上是不必要的优化。 p>

原因很简单:如果您需要一种高效的模式搜索,那么无论如何您都将实现自己的模式,并根据您的特定数据进行定制。所以没有必要在通用库中实现一些花哨的东西。


截至 2016 年(现已提供 Core CLR 源代码),实现仍在使用简单的嵌套循环。这是在NewApis::IndexOfStringNewApis::FastIndexOfString 中实现的,它们从托管的String.ContainsString.IndexOf 函数中调用(通过InternalFindNLSStringEx)。

【讨论】:

  • 感谢您的合理回答。
  • 我完全同意;如果库中已经有一个,为什么要实现自己的通用字符串搜索?此外,字符串搜索算法是个例外,因为 Boyer-Moore 非常好(所有赞成没有反对)被认为是标准基准。我的意思是,通常为库选择算法可能真的很困难,但是对于字符串,我不希望在任何有价值的库中使用更少的东西。如果我错了,请纠正我。
  • @Unreason:在大多数应用程序中,这根本不重要。将Find 用于除琐碎任务之外的任何事情都会导致复杂的逻辑和代码膨胀。最好使用正则表达式或解析器。在您确实需要使用模式查找的地方以及重要的地方,您很少处理 Unicode。它通常像 DNA 序列一样高度专业化。而且当然你不会自己编程——你使用现成的库。但这些都是专门的,不属于像 .NET 框架这样的通用框架。
  • @Unreason:Boyer-Moore 严重依赖于 Unicode 所禁止的字母的大小。可以修改算法以使用散列代替,但参数已经变得模糊不清。我认为很少有人在像 .NET 这样的通用框架上工作,知道如何在不增加实现成本的情况下做到这一点(比一般情况下的幼稚搜索更有效,并且 100% 没有错误)。
  • (续)最后,Boyer-Moore 绝不是硬道理。 Horspool 通常(大部分时间?)更有效(更不用说更容易实现)。我确信有一些现代变体可以对 Horspool 进行更多的调整。而且,在没有执行任何基准测试的情况下,我敢打赌,对于大多数应用程序(即相对小的 Unicode 字符串),天真的搜索无疑会胜过 Horspool。
【解决方案2】:

我找不到那个方法存根,但我最好的猜测是它会针对不区分大小写的搜索进行本地特定的大小写折叠。

【讨论】:

    【解决方案3】:

    source code 可用时,为什么要使用反射器?

    【讨论】:

    • 这仍然不会向您显示任何本机/内部代码,就像此方法一样。
    • 我试图使用源代码,但它没有显示算法。是我做错了什么还是没有办法看到真正的实现?
    • 另外,您应该在评论中添加 Thin,而不是答案
    猜你喜欢
    • 2011-08-15
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2012-01-24
    • 1970-01-01
    • 2013-11-29
    • 1970-01-01
    相关资源
    最近更新 更多