【问题标题】:haskell: a data structure for storing ascending integers with a very fast lookuphaskell:一种用于存储升序整数的数据结构,查找速度非常快
【发布时间】:2023-03-18 22:45:01
【问题描述】:

(这个问题与我的previous question有关,或者更确切地说与my answer有关。)

我想将所有自然数的 qube 存储在一个结构中,并查找特定的整数以查看它们是否是完美的立方体。

例如,

cubes = map (\x -> x*x*x) [1..]
is_cube n = n == (head $ dropWhile (<n) cubes)

它比计算立方根快得多,但它的复杂度为O(n^(1/3))(我说的对吗?)。

我认为,使用更复杂的数据结构会更好。

例如,在 C 中,我可以存储已经生成的数组的长度(不是列表 - 用于更快的索引)并进行二进制搜索。对于 that 问题,O(log n) 的效率低于another answer。问题是,我无法用 Haskell 表达它(而且我认为我不应该)。

或者我可以使用哈希函数(如mod)。但是我认为拥有多个列表(或列表的列表)会消耗更多内存,并且不会降低查找的复杂性(仍然是O(n^(1/3))),只是一个系数。

我想到了一种树,但没有任何聪明的想法(遗憾的是我从未学过 CS)。我认为,所有整数都在升序的事实会使我的树在查找时不平衡。

而且我很确定关于升序整数的这一事实对于查找来说可能是一个很大的优势,但我不知道如何正确使用它(请参阅我无法用 Haskell 表达的第一个解决方案)。

【问题讨论】:

    标签: data-structures haskell lookup


    【解决方案1】:

    几个cmets:

    • 如果您的立方体数量有限,请将它们放入Data.IntSet。查找是对数时间。算法基于 Patricia 树以及 Gill 和 Okasaki 的论文。

    • 如果排序列表中有无限多的立方体,则可以进行二分搜索。从索引 1 开始,您将以对数方式将其翻倍,直到获得足够大的东西,然后以对数方式执行更多步骤以找到您的整数或将其排除。但不幸的是,对于列表,每次查找都与索引的大小成正比。而且你不能用恒定时间查找创建一个无限的数组

    在此背景下,我提出以下数据结构:

    多维数据集的排序数组的排序列表。位置i 的数组包含exp(2,i) 元素。

    然后你有一个稍微复杂的二分搜索形式。 我还不够清醒,无法从头顶上进行分析,但我相信这会让你达到 O((log n)^2) 最坏的情况。

    【讨论】:

      【解决方案2】:

      您可以对惰性无限树进行斐波那契搜索(或任何其他您喜欢的方法):

      data Tree a = Empty
                  | Leaf a
                  | Node a (Tree a) (Tree a)
      
      rollout Empty = []
      rollout (Leaf a) = [a]
      rollout (Node x a b) = rollout a ++ x : rollout b
      
      cubes = backbone 1 2 where
          backbone a b = Node (b*b*b) (sub a b) (backbone (b+1) (a+b))
      
          sub a b | (a+1) == b = Leaf (a*a*a)
          sub a b | a == b = Empty
          sub a b = subBackbone a (a+1) b
      
          subBackbone a b c | b >= c = sub a c
          subBackbone a b c = Node (b*b*b) (sub a b) (subBackbone (b+1) (a+b) c)
      
      is_cube n = go cubes where
          go Empty = False
          go (Leaf x) = (x == n)
          go (Node x a b) = case (compare n x) of
                                EQ -> True
                                LT -> go a
                                GT -> go b
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-02
        • 1970-01-01
        • 2014-06-23
        • 2011-04-02
        • 2011-04-09
        • 2011-04-07
        • 1970-01-01
        相关资源
        最近更新 更多