【问题标题】:How to use 'cons' without generating nested lists in Scheme?如何使用'cons'而不在Scheme中生成嵌套列表?
【发布时间】:2010-11-05 19:28:06
【问题描述】:

在尝试生成存在于两个集合中的子集列表时,我遇到了 cons 的问题。一个过程接收一个名为 result 的列表,并尝试从 result 和另一个集合的 car 中构造一个新列表。到目前为止,该集合是使用正确的元素生成的,但它们包含在大小 N 嵌套列表中,其中 N 是嵌套数和我正在搜索的子集中的元素数.

如何在不创建嵌套列表的情况下应用 consresult

例子:

;These are two sets that I will be checking
(define s1 '(1 2 3 4))
(define s2 '(1 2 3))
;Result from running these lists through my procedure
(((() . 1) . 2) . 3)
;What I want to have generated
(1 2 3)

我需要能够拨打 (car list) 并接收1 而不是((() . 1) . 2)

【问题讨论】:

    标签: list scheme append


    【解决方案1】:

    首先(((() . 1) . 2) . 3) 不是一个嵌套列表——它根本不是一个列表。 (((() 1) 2) 3) 将是一个嵌套列表。 (((() . 1) . 2) . 3) 是一个点对,它的第一个元素也是一个点对。

    所以现在解释一下你看到的行为:在 lisp 语言家族中,(cons a b) 创建了一个包含 a 的对,因为它是 carb 作为它的 cdr

    现在列表要么是空列表 (()),要么是其 cdr 也是列表的一对(car 可能包含任何内容 - 如果 cdrcar 都是列表,该列表称为嵌套列表)。

    不是列表的对称为点对。这是您在此处创建的内容,因为您使用第二个参数而不是列表调用 cons

    结论:

    您不能使用cons 追加到列表的末尾。如果您需要追加到列表的末尾,您可以使用 concat 和单元素列表作为第二个参数。

    但是请注意,附加到列表末尾是一个O(n) 操作,而在前面附加(使用cons)是一个O(1) 操作,所以如果可能的话你应该改变你的算法,所以它只需要附加在前面。

    【讨论】:

    • 我错误地传递了一个点对作为 cons 的第一个参数。当我按如下更改顺序时,一切正常。 ;Broken method (cons result (car s2)) ;正常工作 (cons (car s2) result)
    • 2个好规则:cons的第二个参数应该是一个列表,每个列表都以'()结尾,意味着一个包含三个子列表的列表里面有4个空列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    • 2015-11-30
    • 2020-06-06
    相关资源
    最近更新 更多