c# - 什么是 startswith 和/或包含搜索的最快的字符串集合结构/算法

标签 c# string algorithm search collections

我有以下情况: 我有一大堆平均长度可能为 30 的字符串(比方说 250.000+)。 我要做的是在这些中进行多次搜索.. 大多数搜索都是 StartsWith 和 Contains 类型的。

该集合在运行时是静态的。这意味着选择集合的初始读取和填充只进行一次..因此构建数据结构的性能绝对不重要。内存也不是问题:这也意味着如果需要的话,我不介意在每个集合中有两个包含相同数据的集合(比如一个用于 startswith,另一个用于包含)。 唯一重要的是搜索的性能,它应该返回与搜索条件匹配的所有元素。

首先,我遇到了 Trie 或 Radix 树 .. 但也许还有更好的选择?

对于包含 .. 我还没有什么好主意(除了在列表上运行 linq 查询之外,对于那么多的数据来说速度不会很快)。

先谢谢大家了!

更新:我忘记了一个重要的部分:包含我的意思是集合中没有完全匹配..但我想找到集合中包含给定搜索字符串的所有字符串

最佳答案

构建 suffix tree将允许您在 O(1) 中并行对所有字符串进行子字符串搜索。我的迂腐不禁注意到它真的是 O(n + m) 其中 n 是与您的子字符串和 m< 匹配的字符串的数量 是被查询子串的大小。

那么你问什么是后缀树?在其最基本的实现中,它是一个带有更高级插入方法的 trie:除了添加一个字符串之外,它还将该字符串的每个可能的后缀添加到 trie。在这个数据结构上,子串搜索变成了所有可能后缀的前缀搜索。由于您还想进行前缀搜索,因此您需要在每个插入的字符串和查询子字符串前添加一个特殊字符。特殊字符可让您区分后缀和完整字符串。

虽然后缀树的这种实现非常简单,但它的效率也非常低(O(n^2) 空间和构建时间)。幸运的是,还有其他更有效的实现可以大大减少空间和时间限制。其中之一,Ukkonen 的算法,在 this SO answer 中得到了很好的解释。并将空间限制降低到 O(n)。您可能还想查看 suffix arrays这是后缀树的等效但更有效的表示。

虽然我知道还有更多的后缀树实现(其中一个可能会满足您的用例),但我只是不了解它们。我建议您在确定实现之前对该主题进行一些研究。

关于c# - 什么是 startswith 和/或包含搜索的最快的字符串集合结构/算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15191885/

相关文章:

c# - 如何在本地正确存储密码

c - 如何增加这个字符串的基地址?

c - Read raw C string to Rust...在此上下文中将有符号转换为无符号的正确方法是什么?

C#:去掉字符串中的多个无效字符

c# - 动态设置Word CustomTaskPane宽度

c# - 将 asp.net 母版页 web 表单输出到 html 电子邮件

algorithm - 如何使用整数代替 float 并降低精度和效率?

c# - 生成带有校验位的唯一公共(public)用户标识符

algorithm - 如何找出一组 point3D 是否在同一平面上?

c# - 用于 C# 作业的弹性 apm