如何在不创建嵌套列表的情况下在erlang中连接列表?

tke*_*rsh 7 erlang list concatenation nested-lists

我想成为一个好的错误并避免"++".我需要在列表的末尾添加一个元组而不创建嵌套列表(希望不必向后构建它并将其反转).给定元组T并列出L0和L1:

当我使用[T | L0]时,我得到[tuple,list0].

但是当我使用[L0 | T]时,我得到嵌套列表[[list0] | tuple].类似地,[L0 | L1]返回[[list0] | list1].

删除外部列表括号L0 | [T]会产生语法错误.

为什么是"|" 不对称?有没有办法用"|"做我想做的事情?

sep*_*p2k 20

|不是"对称的",因为非空列表有头部和尾部,其中头部是单个项目而尾部是另一个列表.在表达式中[foo | bar] foo表示列表的头部并且bar是尾部.如果尾部不是正确的列表,则结果也不是正确的列表.如果head是一个列表,结果将只是一个列表,该列表作为其第一个元素.

在少于O(n)的时间内无法在链表的末尾追加.这就是为什么++通常避免使用它的原因.如果在列表的末尾附加特殊语法,它仍然需要花费O(n)时间并且使用该语法不会使你成为一个"好的错误"而不是使用它++.

如果要避免每次插入的O(n)成本,则需要先添加然后反转.如果您愿意支付费用,您也可以使用++.

关于列表如何工作的更多细节:

[ x | y ]是一种称为利弊细胞的东西.在C语言中,它基本上是一个有两个成员的结构.正确的列表是空列表([])或其第二个成员是正确列表的cons单元格(在这种情况下,第一个成员称为其头部,第二个成员称为其尾部).

因此,当你写[1, 2, 3]这个时,会创建以下缺点:[1 | [2 | [3 | []]]].即列表表示为cons单元,其第一个成员(其头部)为1,第二个成员(尾部)为另一个cons单元.另一个cons细胞有2个作为其头部,而另一个cons细胞作为它的尾部.那个单元格的头部为3,尾部为空列表.

遍历这样的列表是通过首先作用于列表的头部然后调用列表尾部的遍历函数来递归地完成的.

现在,如果您想要将一个项目添加到该列表中,这非常简单:您只需创建另一个缺点单元格,其头部是新项目,其尾部是旧列表.

然而,附加项目要昂贵得多,因为创建单个cons单元是不够的.你必须创建一个与旧的列表相同的列表,除了最后一个cons单元格的尾部必须是一个新的cons单元格,其头部是新元素,其尾部是空列表.因此,如果不通过整个列表(即O(n)),则无法附加到列表中.

  • 我认为你的前置 - 然后 - 逆转的部分建议需要更多的背景.如果它作为一个操作完成一次,那么只需附加值就可以了.在这种情况下,两个操作最终都是O(n).但是,当您在递归函数中重复附加值时,则需要追加N次,从而获得O(n²)复杂度.那就是前期 - 然后逆转是值得的.前置是O(1),你做N次.反转也是O(n),它给你一个O(2n),或者只有O(n),它优于O(n²). (3认同)