【问题标题】:How to efficiently search on a String如何有效地搜索字符串
【发布时间】:2011-08-28 00:00:03
【问题描述】:

我有一个大约 300 到 500 个字的文本。另外我得到了大约 200k 个关键字,我想知道每个关键字是否都包含在文本中。 String 包含 ist 很慢,有什么方法可以预处理 String 吗?

我考虑过使用 SuffixTree,但我不确定这是最佳选择。

另外,有没有适合这个任务的库?例如,semanticdiscoverytoolkit 有一个后缀树实现,但是在添加字符串后,我不知道如何查找树中是否包含字符串。

你好,

尼哥

【问题讨论】:

  • 关键字是整个词还是词的一部分?
  • 大部分时间都是整个单词。正文是pubmed的摘要,关键词是已知基因和疾病

标签: java string search text


【解决方案1】:

你可以试试 rabin-karp 字符串搜索算法。由于您主要进行哈希(整数)比较,因此性能比字符串比较好得多。

  1. 计算关键字的哈希
  2. 计算文本的滚动哈希
  3. 比较这两个哈希值。如果它们匹配,则执行实际的字符串比较。
  4. 将位置前移 1 个字符,然后从第 2 步开始重复,直到到达文本末尾。

打个比方,滚动哈希就像一个沿着文本滚动的“滑动窗口”。哈希比较是使用“滑动窗口”中的子字符串的哈希与关键字的哈希来完成的。

【讨论】:

  • 如果我理解正确:我有长文本和关键字,现在我想知道长文本中是否包含关键字。我制作了一个与关键字长度相同的滑动窗口,让它沿着文本滚动。对于每一步,我都会计算窗口的哈希值和关键字的哈希值,现在我将它们与 rabin-karp 进行比较?
  • @Nicolas 你明白了。整个 4 步过程是 rabin-karp 算法。我认为 rabin-karp 比 suffixtree 更好,因为单独构建 suffixtree 的运行时间比 rabin-karp 搜索算法要长。一个重要的注意事项:您必须能够在线性时间内计算散列函数,理想情况下,应该有最小的冲突。当然,您可以尝试使用默认的字符串哈希函数,并在充实实现细节时对其进行调整。
  • @Nicolas:在 Rabin-Karp 上查看这些 Java 代码示例:mcs.uwsuper.edu/sb/425/Prog/RabinKarp.javaalgs4.cs.princeton.edu/53substring/RabinKarp.java.html
  • 有人知道实现 rabin-karp 搜索的库吗?
  • 没有用于字符串搜索算法的 java 库,但您可以使用 anubhava 列出的任一实现。您可能需要调整它们以满足您的需求,例如您必须预先计算所有关键字的哈希并将它们存储在二叉搜索树中,以便以后检索。
【解决方案2】:

您可以使用 StringTokenizer 来获取每个单词,然后填充您之后检查的哈希图。这只需要遍历每个列表一次。鉴于您拥有的关键字数量,查找时间应该非常快。

将这种方法与 Lucene 之类的东西进行对比可能是值得的。

【讨论】:

  • 问题是,使用字符串分词器方法,我无法找到在分词后最多分成 2 个词的组合词
猜你喜欢
  • 2017-09-21
  • 1970-01-01
  • 2020-12-21
  • 1970-01-01
  • 2020-10-13
  • 2018-08-05
  • 2016-02-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多