通过子字符串快速过滤字符串集合?
Posted
技术标签:
【中文标题】通过子字符串快速过滤字符串集合?【英文标题】:Fast filtering of a string collection by substring? 【发布时间】:2010-11-20 21:56:05 【问题描述】:你知道一种快速过滤字符串列表以获得包含指定字符串的子集的方法吗?显而易见的实现是遍历列表,检查每个字符串是否包含搜索字符串。有没有办法对字符串列表进行索引,以便更快地完成搜索?
【问题讨论】:
【参考方案1】:Wikipedia article 列出了几种索引子字符串的方法。你有:
Suffix tree Suffix array N-gram 索引,文本的所有 N-gram 的反转文件 压缩后缀数组1 FM-index LZ-索引
【讨论】:
【参考方案2】:是的,例如,您可以为字符串中的所有字符组合创建索引。像“hello”这样的字符串将被添加到“he”、“el”、“ll”和“lo”的索引中。要搜索字符串“hell”,您将获取所有“he”、“el”和“ll”索引中存在的所有字符串的索引,然后遍历这些索引以检查字符串中的实际内容。
【讨论】:
当然,这取决于数据在优化方面的实际效果。 这个算法叫什么?我最近实现了这一点,它相当简单,并为我的特定用例带来了显着的速度提升。 啊,这似乎是所有二元组的倒排索引(n-gram,其中 n = 2)。【参考方案3】:如果您可以预处理集合,那么您可以做很多不同的事情。
例如,您可以构建一个包含所有字符串后缀的 trie,然后使用它进行非常快速的匹配。
【讨论】:
【参考方案4】:如果您要重复搜索相同的文本,那么suffix tree 可能是值得的。如果仔细应用,您可以对大多数字符串问题实现线性时间处理。如果不是,那么在实践中你将无法比Rabin-Karp 做得更好,它基于散列,并且在预期时间内是线性的。
有许多免费提供的后缀树实现。例如,请参见 C implementation,或者对于 Java,请查看 Biojava 框架。
【讨论】:
【参考方案5】:实际上没有任何可行的方法,不,除非您对您的数据和/或搜索词有额外的先验知识 - 例如,如果您只在您的开头搜索匹配项字符串,然后您可以对字符串进行排序,只查看搜索词范围内的字符串(甚至将它们存储在二叉树中,只查看可能匹配的分支)。同样,如果您的潜在搜索字词有限,您可以在最初输入字符串时针对该字符串运行所有可能的搜索,然后只需存储一个表格,其中包含哪些字词匹配哪些字词不匹配。
除了那种东西,基本上只是迭代而已。
【讨论】:
【参考方案6】:这取决于子字符串是在字符串的开头还是可以在字符串中的任何位置。
如果它在任何地方,那么您几乎需要遍历整个列表,除非您的列表太大并且查询发生的频率足够高,值得构建更复杂的索引解决方案。
如果子字符串在字符串的开头,那么这很容易。对列表进行排序,通过二分搜索找到开始/结束并获取该子集。
【讨论】:
以上是关于通过子字符串快速过滤字符串集合?的主要内容,如果未能解决你的问题,请参考以下文章