【问题标题】:SML: How to append an element to a list in SML?SML:如何将元素附加到 SML 中的列表中?
【发布时间】:2017-08-06 20:53:53
【问题描述】:

SML 中是否有一个运算符允许我在不必创建新列表的情况下追加到列表中?例如

我不能这样做:

 [1,2,3]::1

但我可以这样做:

 [1,2,3]@[1]

这很奇怪,因为我必须创建一个包含 1 的列表。有更好的方法吗?

【问题讨论】:

  • 正如@sepp2k 所说,附加到列表的末尾很昂贵。构建列表的最慢方法之一是将元素一个一个地附加到列表的末尾,因为任何这样的方法在列表的长度上最多是二次方的。出于这个原因,SML 程序员有时会编写函数以向后顺序创建列表(追加到前面而不是后面,即使在追加到后面看起来更自然的情况下)然后通过rev 运行结果列表(其中以一种巧妙的方式实现,因此它是O(n)) 来获取所需的列表。
  • 没有尾指针可以追加吗?这也将是 O(1)
  • @Har 附加到尾指针(如果有的话,则没有)会改变原始列表。 SML 列表是不可变的,所以这是不可能的。
  • @Har 是正确的,没有尾指针可以追加。

标签: sml


【解决方案1】:

无论哪种方式,您都必须创建一个包含一个列表的列表。 [1,2,3,1]的尾巴的尾巴是[1]。因此,如果您在内存中有[1,2,3,1],那么您在内存中的某处也有[1]。

所以即使有像[1,2,3] @:: 1 这样的运算符,它也不会有什么不同,因为它仍然需要创建一个包含一个的列表。

PS:xs @ [x] 的真正问题不是创建列表,而是它的运行时间在 O(n) 中(而不是 x :: xs,在 O(1) 中)。这也是不可变单链表的本质固有的问题,因此无济于事,但这就是为什么您通常应该避免附加到这样的列表末尾的原因。

【讨论】:

  • 1.你还会如何附加到列表中? 2. 他们不存储您要附加到的尾指针吗? 3. x::xs 究竟做了什么?创建一个新列表还是追加到头指针?
  • SML 中的列表是作为链接结构还是作为数组实现的?
  • @Har SML 列表是不可变的,单链表。它们完全等同于datatype list 'a = Cons of 'a * 'a list | Nil,其中Cons 代替了::,Nil 代替了[]。所以他们一个非空列表有一个头部值和另一个列表是它的尾部。这两个都不能改变。 x :: xs 创建一个新列表,其中 x 作为头部值,xs 作为尾部。
  • "你还怎么附加到一个列表中?"如果可以避免,我不会。相反,我会在前面使用::。例如,如果您尝试追加多次,则多次追加然后反转列表更有意义。
【解决方案2】:

[1,2,3]::1 尝试将 int 列表 [1,2,3] 附加到整数值 1 中,这是不可能的,因为无法附加整数。
1::[1,2,3] 但是,作为列表 @ 是完全有效的987654325@支持追加操作。 :: 的评估规则需要 t1 :: t1 list,其中 t1 是来自类型 1 的值,而 t1 list 是类型 1 的列表,你正在做的是 t1 list :: t1。
[1,2,3] @ [1] 是有效的,因为您正在将列表附加到列表中。

【讨论】:

    猜你喜欢
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 2021-01-20
    • 2016-02-03
    • 2017-09-19
    相关资源
    最近更新 更多