最简单的方法是简单地使用库函数flatten
。
(define (merge lis1 lis2)
(flatten (cons lis1 lis2)))
flatten
需要,可以包含列表(谁又可以包含多个列表,...)的列表,并将结果合并为未列出的清单,这是你的组合功能似乎什么是试图去做。
(flatten '(1 2 (3 (4 5) 6)))
回报'(1 2 3 4 5 6)
如果这个库的功能是关闭的限制,你的代码实际上是相当接近正确。
第一个问题是在((list? lis) (combine (car lis) fine) (combine (cdr lis) fine) )
行。 fine
永不改变,因此代码评估(combine (car lis) fine)
,然后返回(combine (cdr lis) fine)
,其中第二个表达式中的fine
是原始值fine
。这条线与((list? lis) (combine (cdr lis) fine) )
相同,显然不是我们想要的。相反,我们必须使用第二个表达式((list? lis) (combine (cdr lis) (combine (car lis) fine)))
中的第一个表达式。
第二个问题是,在组合中,当lis
为空时,我们需要返回fine
而不是lis
。
下一个问题是,这段代码遍历列表,将lis
的第一个元素放在fine
的前面,然后传递新创建的列表并将其用于下一次函数迭代,其中它在lis
中取第二个值,并将其粘贴在新的fine
的前面,在lis
的第一个值前面。返回值为fine
的结果顺序颠倒 - (merge '(1 2 (3)) '(4 (5 6)))
将返回(6 5 4 3 2 1)
。我们有两种选择:我们可以在merge
正文中从combine
返回,或者我们可以反转我们上面更改的行,使其成为((list? lis) (combine (car lis) (combine (cdr lis) fine)))
。这意味着在添加当前元素之前,我们会将列表的其余部分添加到fine
,这正是我们想要的。
另一个问题是我们需要将lis1
改为lis2
,而不是相反。
最后一个问题是merge
正文中的cond
是不必要的 - 我们可以将其删除。
作为一个方面说明,通常认为整齐的方法是不要给圆括号一个新的行,并将define
或cond
的主体缩进两个空格。
所有这些变化,最终的代码是:
(define (merge lis1 lis2)
(define (combine lis fine)
(cond
((null? lis) fine)
((list? lis) (combine (car lis)
(combine (cdr lis) fine)))
(else (cons lis fine))))
(combine (cons lis1 lis2) '()))