代码之家  ›  专栏  ›  技术社区  ›  Valentin Golev

haskell:一种数据结构,用于存储具有非常快速查找的升序整数。

  •  2
  • Valentin Golev  · 技术社区  · 14 年前

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

    我想把所有自然数的量子点存储在一个结构中,然后查找特定的整数,看看它们是否是完美的立方体。

    例如,

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

    它比计算多维数据集根快得多,但它的复杂性是 O(n^(1/3)) (我说得对吗?).

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

    例如,在C中,我可以存储一个已经生成的数组的长度(而不是列表,以便更快地建立索引),并执行二进制搜索。它将会是 O(log n) 效率低于 another answer 那个 问题。问题是,我不能用haskell来表达(我认为我不应该)。

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

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

    我很确定关于整数升序的这个事实对于查找是一个很大的优势,但是我不知道如何正确地使用它(见我在haskell中无法表达的第一个解决方案)。

    2 回复  |  直到 14 年前
        1
  •  4
  •   Norman Ramsey    14 年前

    几点意见:

    • 如果你有有限的立方体,把它们放进去 Data.IntSet . 查找是对数时间。该算法是基于帕特里夏树和一篇论文吉尔和冈崎。

    • 如果排序列表中有无限多的多维数据集,则可以执行二进制搜索。从索引1开始,您将对数加倍多次,直到得到足够大的值,然后再对数多次,以找到整数或将其排除。但不幸的是,对于列表,每次查找都与索引的大小成比例。你不能创造无限 数组 使用持续时间查找。

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

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

    然后是稍微复杂一点的二进制搜索形式。 我还没有清醒到可以从头开始分析,但我相信这会让你陷入最坏的情况。

        2
  •  2
  •   ony    14 年前

    您可以在懒惰的无限树上执行斐波那契搜索(或任何其他您喜欢的搜索):

    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