我正在尝试在Clojure中实现堆栈的行为。从frequencies
的实现中获得提示,我创建了一个瞬态向量,我正在conj!
将元素添加到(la“ push”)。我的问题是pop!
从末尾删除元素,而其他一些fns(rest
,drop
)仅适用于惰性序列。
我知道我可以使用loop/recur
(或reverse
和pop!
ing来完成此操作,但是我想更好地理解为什么不允许从瞬态矢量的开头删除。我读过this,是因为允许它们突变的实现只有O(1),因为您只在最后编辑节点,并且如果您更改了第一个需要复制整个向量的节点,那么
答案 0 :(得分:0)
您的困难不在于瞬变:pop
和peek
总是像conj
那样在集合的同一端工作:
所以...
(= (pop (conj coll x)) coll)
和
(= (peek (conj coll x)) x)
...对于实现x
的任何coll
的任何IPersistentStack
都是正确的:
如果要同时查看堆栈,请使用向量,并使用(恒定时间)rseq
对其进行反转。但是,由于没有rseq!
,因此您必须离开瞬态。请(comp rseq
坚持不懈!)
仍然是永恒的时间。
顺便说一下,rest
和drop
可以在任何sequence上工作,无论是否懒惰:
=> (rest [1 2 3])
(2 3)