【问题标题】:remove first element of a transient vector删除瞬态向量的第一个元素
【发布时间】:2019-11-21 23:05:35
【问题描述】:

我正在尝试在 Clojure 中实现堆栈的行为。从frequencies 的实现中得到启发,我创建了一个瞬态向量,我是conj!ing 元素(一个“推”)。我的问题是 pop! 从末尾删除元素,而其他一些 fns (rest,drop) 仅适用于惰性序列。

我知道我可以使用loop/recur(或reverseing 和pop!ing)来完成此操作,但我想更好地理解为什么不允许从瞬态向量的开头删除。我读了this,是不是因为允许它们被变异的实现只有 O(1),因为你只在最后编辑节点,如果你更改了需要复制整个向量的第一个节点?

【问题讨论】:

  • 仅供参考 Clojure 的列表可以用作堆栈。 ``` (def stack '(:b :c)) (peek stack) (pop stack) (cons :a stack) ``
  • 是的,可以。但正如我所说,我试图模仿 frequencies 的行为,它使用不能转换为列表的transient 以及 可以 转换为瞬态的所有数据结构(例如。 vector) 实现 pop 作为删除最后一个元素。

标签: clojure stack


【解决方案1】:

您的困难不在于瞬变:poppeek 始终与 conj 一样在集合的同一端工作:

  • 向量的结尾或
  • 列表的头部。

所以...

(= (pop (conj coll x)) coll)

(= (peek (conj coll x)) x)

...对于实现IPersistentStack 的任何coll 的任何x 都是正确的:

  • 向量和列表可以。
  • Conses 和 Ranges 没有。

如果您想以两种方式查看堆栈,请使用向量,并使用(恒定时间)rseq 来反转它。但是,您必须留下瞬变,因为没有rseq!。请注意(comp rseqpersistent!) 仍然是恒定的时间。


顺便说一句,restdrop 可以在任何 sequence 上工作,不管你是否懒惰:

=> (rest [1 2 3])
(2 3)

【讨论】:

    猜你喜欢
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 2022-01-25
    • 1970-01-01
    • 2019-05-10
    相关资源
    最近更新 更多