2017-06-23 24 views
-2

我如何追加(1 2 3)()末,使((1 2 3))
我如何追加(4 5 6)末,使((1 2 3) (4 5 6))
我如何追加"|"即将制作的末尾((1 2 3) (4 5 6) "|")我怎么可以追加到一个列表,而无需创建一个点对

没有虚线对。

我正在与鸡计划,但我会采取任何方案在这一点上的答案。请注意,这些列表中的任何一个都可能是嵌套列表,谁知道什么......我只是写了一个简单的例子。

注意:@sjamaan显示a使用append的解决方案,涉及将所有内容封装到另一个列表中以补偿附加事务而非名称所示。

(append (list 1 2 3) "|") ;=> (1 2 3 . "|") ;^^ didn't actually append, created a dotted pair (append '(1 2 3) (list 4 5 6)) ;=> (1 2 3 4 5 6) ; don't want unwrapped list ;^^ didn't actually append the list i gave it but appended the contents of the list.

基本上我希望,实际上追加你给它的append方法,不追加它的内容,或者需要它,使一个点对。也许我只是一个梦想家......我可以写一个“不真正追加”的方法,只需要你给它的任何参数,并将它们包装在一个外部列表中以弥补,但这只是愚蠢的......当然,方案有一定的方法追求没有这个疯狂。

+0

的[什么是“缺点”可能的复制将项目添加到列表的末尾?](https://stackoverflow.com/questions/6439972/what-is-the-cons-to-add-an-item-to-the-end-of-the-list) – jcolemang

+0

@jcolemang它是相似的,但不是相同。另一个问题很模糊,并没有涵盖相同的理由。它及其答案未能解决附加列表不附加列表而是内容的事实,并且不涉及附加单个项目。 – masukomi

回答

3

下面是如何追加由:

(define (append2 lst1 lst2) 
    (if (null? lst1) 
     lst2        ; the second list is unaltered 
     (cons (car lst1) 
      (append2 (cdr lst1) lst2)))) 

使得由在lst1lst2所有元素的一对链。它不会使一对lst2哪里有nont这样:

(append2 '(1 2 3) '(4 5)) ; ==> (1 2 3 4 5) 
(append2 '(1 2 3) '()) ; ==> (1 2 3) and not (1 2 3()) 
(append2 '(1 2 3) '5)  ; ==> (1 2 3 . 5) 

注意,像(1 2 3)每个列表实际上是(1 2 3 .())或者更正确地(1 . (2 . (3 .())))

我如何追加(1 2 3)到年底()使((1 2 3))

(define (insert-last e lst) 
    (let helper ((lst lst)) 
    (if (pair? lst) 
     (cons (car lst) 
       (helper (cdr lst))) 
     (cons e '())))) 

(insert-last '(1 2 3) '())      
; ==> ((1 2 3)) 

我如何追加(4 5 6)末,使((1 2 3) (4 5 6))

(insert-last '(4 5 6) '((1 2 3))) 
; ==> ((1 2 3) (4 5 6)) 

我如何追加"|"末,使((1 2 3) (4 5 6) "|")

(insert-last "|" '((1 2 3) (4 5 6))) 
; ==> ((1 2 3) (4 5 6) "|") 

知道这非常像append。由于您每次都创建一个新列表,因此这是制定该列表的最糟糕方式。每个插入的O​​(n)和n个元素的O(n^2)。如果你可以按照相反的顺序来做到这一点,那么你可以得到这样的结果:O(1)代替O(n)。代替insert-last使用cons

(cons '"|" '())    ; ==> ("|") 
(cons '(4 5 6) '("|"))  ; ==> ((4 5 6) "|") 
(cons '(1 2 3) '((4 5 6) "|") ; ==> ((1 2 3) (4 5 6) "|") 

这是O(1),O(N),用于处理n个元素。如果您需要做的是在原来的顺序可以积累,再反向..

(cons '(1 2 3) '())    ; ==> ((1 2 3)) 
(cons '(4 5 6) '((1 2 3)))   ; ==> ((4 5 6) (1 2 3)) 
(cons '"|" '((4 5 6) (1 2 3))) ; ==> ("|" (4 5 6) (1 2 3)) 
(reverse '("|" (4 5 6) (1 2 3)) ; ==> ((1 2 3) (4 5 6) "|") 

这是O(1),然后为O(n)为反向,但它仍然是O(1)摊销。 O(n)为您处理的n元素。

+0

感谢您回答这个问题所花费的时间和精力。我会注意到,附加的'“|”'答案不是_quite_正确的,但你肯定回答了问题的核心。 – masukomi

+0

@masukomi我已经更新了解决''|“' – Sylwester

+1

的答案,我偶然听说过'insert-last'叫'snoc'。 –

2

您正在查找的程序不会令人惊讶地称为append(来自SRFI-1)。它将一系列事物附加到另一个列表中。这并不意味着,如果你想添加只有一个项目,你需要做一个清单出来的:

(append '() '((1 2 3))) => ((1 2 3)) 
(append '((1 2 3)) '((4 5 6))) => ((1 2 3) (4 5 6)) 
(append '((1 2 3) (4 5 6)) '("|")) => ((1 2 3) (4 5 6) "|") 

它接受多个参数,这都将按照这个顺序被追加到海誓山盟,让你也可以这样做:

(append '() '((1 2 3)) '((4 5 6)) '("|")) => ((1 2 3) (4 5 6) "|") 

希望这有助于!

+0

我明白你在做什么,但并不完全一样。不同之处在于,你正在通过将所有内容包装到另一个列表中来解决append的愚蠢问题。添加另一个列表的项目就像'(map(labmda(x)(append destination-list(list x))source-list)'。我希望找到一个不是“嘿,将所有内容嵌套到另一个列表中,因为append是愚蠢的,然后执行它。“是否没有更直接的版本? – masukomi

+0

答案的确是将所有内容都包含在列表中。原因是append已经**有**来重建列表单元格除了最后一个列表(包含原子)之外的所有列表的结构对于列表来说,它偶尔会这样做很有意义,但在最后不断添加原子是非常低效的,因此没有任何意义一个专门的程序就是为了这个,所以,如果你这样做的话,看看@ dan-d的建议是保持反向列表,不断向前反向并在最后反转一次,这是Scheme中的典型使用模式。 – sjamaan

+0

或者,您可以保留列表中的最后一个cdr并调用'se t-cdr!'带(再次)包含原子的列表。我只会建议在性能关键的代码中这样做,因为它掩盖了你的算法,并且如果列表中传入了调用者的数据。请注意,这是使用C或其他命令式语言的单链表执行此操作的典型方法。 – sjamaan

3

append不会将原子追加到列表中。它连接列表。在连接有意义之前,必须将原子提升到一个列表。

(append xs (list y)) 

但它是有道理指出(reverse (cons y (reverse xs)))具有相同的结果。 reverse表明如果您需要将原子追加到最后,您可能会向后建立列表。

0

无论您是否愿意,都会创建cons单元格,因为列表由cons单元格组成。

我如何追加(1 2 3)的()进行((1 2 3))

CL-USER 24 > (list '(1 2 3)) 
((1 2 3)) 

我如何追加(4 5 6)的端到的,端,使((1 2 3)(4 5 6))

CL-USER 25 > (append '((1 2 3)) (list '(4 5 6))) 
((1 2 3) (4 5 6)) 

我如何追加 “|”到的,端,使((1 2 3)(4 5 6)“|”)

CL-USER 26 > (append '((1 2 3) (4 5 6)) (list "|")) 
((1 2 3) (4 5 6) "|") 
相关问题