Lisp 合并和提取列表
我正在编写一个合并两个列表的函数。如果列表中的一个项目是列表,我也需要提取它Lisp 合并和提取列表,lisp,scheme,Lisp,Scheme,我正在编写一个合并两个列表的函数。如果列表中的一个项目是列表,我也需要提取它 list1:'(1 (2 3 4) 5 6)) list2: '(7 (8 9) 10 (11)) output: (1 2 3 4 5 6 7 8 9 10 11) 我试图用我的代码来解决它,但代码不起作用。有什么问题 (define (merge lis1 lis2) (define (combine lis fine) (cond ((null? lis)
list1:'(1 (2 3 4) 5 6))
list2: '(7 (8 9) 10 (11))
output: (1 2 3 4 5 6 7 8 9 10 11)
我试图用我的代码来解决它,但代码不起作用。有什么问题
(define (merge lis1 lis2)
(define (combine lis fine)
(cond
((null? lis) lis)
((list? lis) (combine (car lis) fine) (combine (cdr lis) fine))
(else (cons lis fine))))
(cond
(combine (cons lis2 lis1) '())))
最简单的方法是简单地使用库函数
flatten
(define (merge lis1 lis2)
(flatten (cons lis1 lis2)))
展平
获取一个可以包含列表的列表(而列表又可以包含更多列表,…),并将结果展平为非列表列表列表,这似乎是您的联合收割机函数所要做的
(展平’(12(3(4 5)6))
返回(1 2 3 4 5 6)
如果这个库函数是禁止使用的,那么您的代码实际上是非常接近正确的
第一个问题出现在((列表?lis)(联合收割机(汽车lis)精细)(联合收割机(cdr lis)精细))行上fine
从未更改,因此代码计算(组合(汽车lis)fine)
,然后返回(组合(cdr lis)fine)
,其中第二个表达式中的fine
是fine
的原始值。这一行与((list?lis)(combine(cdr lis)fine))相同,这显然不是我们想要的。相反,我们必须在第二个表达式中使用第一个表达式((list?lis)(combine(cdr lis)(combine(car lis)fine))
第二个问题是,在combine中,当lis
为空时,我们需要返回fine
,而不是lis
下一个问题是,此代码遍历列表,获取lis
的第一个元素并将其放在fine
的前面,然后传递新创建的列表并将其用于函数的下一次迭代,其中它在lis
中获取第二个值并将其粘贴在新fine
的前面,在lis的第一个值前面
。按照fine
的返回值被反转的顺序--(merge'(1 2(3))(4(5 6))
将返回(6 5 4 3 2 1)
。我们有两种选择:我们可以在merge
主体中的combine
返回时调用reverse,或者我们可以反转上面更改的行,使其((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) '()))