【问题标题】:An effective way to perform a prefix search on ranked (sorted) list?在排名(排序)列表上执行前缀搜索的有效方法?
【发布时间】:2019-08-13 14:45:56
【问题描述】:

我有一个按概率排序的一些元素的大列表:

data class Element(val value: String, val probability: Float)

val sortedElements = listOf(
    Element("dddcccdd", 0.7f),
    Element("aaaabb", 0.2f),
    Element("bbddee", 0.1f)
)

现在我需要对该列表执行前缀搜索,以查找以一个前缀开头然后以下一个前缀开头的项目,依此类推(元素仍然需要按概率排序)

val filteredElements1 = sortedElements
                                  .filter { it.value.startsWith("aa") }

val filteredElements2 = sortedElements
                                  .filter { it.value.startsWith("bb") }

每个由某个前缀过滤的元素的“请求”都需要 O(n) 时间,这在列表很大的情况下太慢了。

如果我不关心元素的顺序(它们的概率),我可以按字典顺序对元素进行排序并执行二进制搜索:排序需要 O(n*log n) 时间,每个请求 - O(log n) 时间。

有没有什么方法可以加快这些操作的执行,同时又不会丢失元素的排序(概率)?也许有某种特殊的数据结构适合这个任务?

【问题讨论】:

  • 为什么不是两个列表?

标签: algorithm sorting kotlin data-structures


【解决方案1】:

你可以阅读更多关于 Trie 数据结构https://en.wikipedia.org/wiki/Trie 这对您的用例可能非常有用。

Leetcode 还有一个非常详细的解释,你可以在这里找到https://leetcode.com/articles/implement-trie-prefix-tree/

希望对你有帮助

【讨论】:

  • 是的,我可以尝试加快前缀搜索,但是在构建 trie 时如何保持排序(概率)?
  • 你的元素可以同时被2个数据结构引用。
【解决方案2】:

如果您的列表不经常更改,您可以创建一个HashMap,其中每个现有前缀都是一个key,指的是它作为前缀的所有条目的集合(按概率排序)。

那么获取给定前缀的所有条目需要~O(1)。

小心地图变得非常大。并且地图的创建需要相当长的时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-20
    • 2012-01-17
    • 2019-02-27
    • 1970-01-01
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多