【问题标题】:How to efficiently search for substrings across all values in a hashmap?如何有效地搜索哈希图中所有值的子字符串?
【发布时间】:2014-09-14 23:25:24
【问题描述】:

我有以下方式指定的数据:

<type:id> <relevance-score> <data>

例如:

a:1 0.8 "This is a post by PhD"
a:2 0.9 "Current rep of PhD is 3,800+"
b:1 1.0 "Pikl F'Nandez is not an existing user on stackoverflow"
c:2 1.0 "AJAX is a tag on stackoverflow"
...

假设将这些值放入哈希图中,这样:

key = (<type:id>) | value = (<relevance-score>,<data>)

现在,如果要搜索关键字PhD,可以在哈希图中的两个条目中找到它。我希望按相关性分数的降序检索与查询字符串匹配的所有键:

Example output: a:2, a:1

查询字符串也可以是PiklPikl FPikl F'n,这意味着字符串匹配算法是进行搜索的最佳方式。

当前方法:对哈希图中的所有值使用 Boyer-Moore 算法,并将结果数据存储到最大堆中(根据相关性得分)。

时间复杂度

  • 博耶-摩尔:O(m+n)
  • 总计,对于每个值 O(q(m+n)) 其中q: # of keys in hashmap
  • 还需要添加从堆中弹出的值。假设O(s) 其中s 是匹配数。由于s &lt;&lt; q 我们可以说上述(搜索)是主要成本。

问题:这是最有效的吗?有什么可以更有效的吗?其他数据结构/算法,我可能没有考虑过?

【问题讨论】:

  • Boyer-Moore 是正确的工具吗?它通过预处理一个正在寻找的模式而不是正在搜索的目标字符串来工作。在这里给你带来什么?
  • 不确定。我只用它来匹配字符串。一种天真的方法开始。想知道是否有更有效的做事方式?你有什么建议?
  • 我们在谈论多少个数据项?另外,是否可以将其存储在具有良好文本搜索能力的 dbms 中?
  • 轻松达到 100,000。这一切都必须“在内存中”才能更快地访问。所以想想从头开始设计这样的能力,上面的方法就是这样的想法。

标签: java performance algorithm data-structures time-complexity


【解决方案1】:

您目前的方法基本上可以归结为:

  1. 遍历所有数据并找到与搜索字符串匹配的数据
  2. 根据相关性分数对所有匹配数据执行堆排序

唯一的区别是你在执行 1 的同时执行 2,但得到的时间复杂度是相同的。

即使我们假设每个字符串搜索的时间为O(1),字符串搜索的总时间为O(q),排序时间为O(slog(s))。由于s &lt;&lt; q,因此声称O(slog(s)) &lt; O(q) 是合理的。换句话说,字符串搜索所花费的时间总是占主导地位。

我能想到的实现有意义的加速的唯一方法是预处理所有数据,以便每个字符串搜索所花费的时间确实更接近O(1)。如果保证查询字符串是单词列表而不是随机子字符串,这将更容易。但是,如果可能使用Pikl F'n 等查询字符串,数据的预处理将非常困难。从本质上讲,如果您有任何关于您可能获得的查询字符串类型的信息,您可以相应地预处理数据以加快搜索速度。

【讨论】:

    猜你喜欢
    • 2014-06-18
    • 2011-08-28
    • 2013-03-05
    • 2011-07-14
    • 1970-01-01
    • 2017-09-21
    • 2014-05-08
    • 2020-12-21
    • 1970-01-01
    相关资源
    最近更新 更多