代码之家  ›  专栏  ›  技术社区  ›  Edward

O(1)haskell中的循环缓冲区?

  •  19
  • Edward  · 技术社区  · 16 年前

    3 回复  |  直到 16 年前
        1
  •  4
  •   yairchu    16 年前

    这个 ST monad允许在Haskell中描述和执行命令式算法。你可以用 STRef s 用于双链接列表的可变指针。

    装货单 runST . 不同的 朗斯特 处决可能不共享 装货单 数据结构( 斯特里夫 , STArray , ..).

    如果算法不是“自包含”的,并且需要在使用之间执行IO操作来维护数据结构,则可以使用 stToIO 要在 IO 蒙纳德。

    关于这是否纯粹是功能性的-我猜不是?

        2
  •  11
  •   C. A. McCann Ravikant Cherukuri    16 年前

    摊销 O(1)操作,您可以使用 Data.Sequence Data.Dequeue finger trees Purely Functional Data Structures (a先前的在线版本) here

        3
  •  2
  •   jberryman    16 年前

    听起来您可能需要比这更复杂的东西(因为您提到了双链接列表),但这可能会有所帮助。此函数的作用类似于 map 在可变循环列表上:

    mapOnCycling f = concat . tail . iterate (map f)
    

    使用类似于:

    *Main> (+1) `mapOnCycling` [3,2,1]
    
    [4,3,2,5,4,3,6,5,4,7,6,5,8,7,6,9,8,7,10,9...]
    

    mapAccumLOnCycling f acc xs = 
        let (acc', xs') =  mapAccumL f acc xs
         in xs' ++ mapAccumLOnCycling f acc' xs'
    

    不管怎样,如果您想更详细地说明您的数据结构究竟需要什么才能“做到”,我真的很想听听。

    :正如camccann提到的,您可以使用 Data.Sequence 对于这一点,根据文档,在查看或向序列的左侧和右侧添加元素以及修改过程中的端点时,应该会给您O1时间复杂性(是否存在O1摊销时间?)。这是否会有你需要的性能,我不确定。

    您可以将“当前位置”视为序列的左端。在这里,我们沿着一个序列来回穿梭,产生一个无限的值列表。抱歉,如果它无法编译,我目前没有GHC:

    shuttle (viewl-> a <: as) = a : shuttle $ rotate (a+1 <| as)
        where rotate | even a    = rotateForward
                     | otherwise = rotateBack
              rotateBack (viewr-> as' :> a')    = a' <| as'
              rotateForward (viewl-> a' <: as') = as' |> a'
    
    推荐文章