【发布时间】:2012-07-14 15:50:40
【问题描述】:
这是我对 FIFO 队列的尝试:
type Queue a = [a] -> [a]
empty :: Queue a
empty = id
remove :: Int -> Queue a -> ([a], Queue a)
remove n queue = (take n (queue []), (\x -> drop n (queue x)));
add :: [a] -> Queue a -> Queue a
add elems queue = (\x -> queue (elems ++ x))
empty 创建一个空队列,remove 获取队列的第一个 n 元素并将队列的其余部分作为元组的第二个元素返回,add 将列表 elems 添加到队列。
这会在O(1) time 中添加/删除 1 个元素,在 O(n) time 中添加/删除 n 个元素吗?
【问题讨论】:
-
也许是我,但我不明白你的代码是如何工作的。你能添加类型签名吗?队列的类型是什么?
-
为什么?
(++)不是 O(1) 操作,它是 O(n),尽管有惰性。 -
@efie:我添加了类型签名。
-
不幸的是,
remove可能需要 O(N) 时间。如果使用 N 个add操作创建队列,remove将需要评估 N 个++操作以找到第一个元素。 -
remove不仅在差异列表上无效,而且也不是特别符合 Haskell 习惯,而且通常比更快的替代方案更麻烦:在一个地方完全建立 FIFO在您的程序(“源”)中,只对它应用一次toList(即$ [])并将结果作为一个整体传递给“消费者”函数。由于懒惰,这不会导致您在开始从另一端开始阅读之前完成构建过程。读数将自动“等待”源产生每个元素。 FIFO 的理想行为,适用于许多问题!