我正在编写一个带有(split L)
列表的递归函数L,并返回一个包含两个子列表的新列表,第一个子列表包含每个第二个元素,L
第二个列表包含不在第一个子列表中的其余元素.
以下是拆分应如何工作的示例:
(split ‘(1 2 3 4 5 6 7 8) ) ( (1 3 5 7) (2 4 6 8))
(split ‘(cat bird dog horse mouse pig tiger gerbil cow) )
( (cat dog mouse tiger cow) (bird horse pig gerbil))
Run Code Online (Sandbox Code Playgroud)
现在这是我的尝试:
(define split
(lambda (L)
(if
(null? L)
'()
(list (first L) (second L))
)
)
)
(define first
(lambda (L)
(if
(null? L)
'()
(cond
(
(null? (cdr L))
(car L)
)
(
#t
(cons
(car L)
(first (cdr (cdr L)))
)
)
)
)
)
)
(define second
(lambda (L)
(if
(null? L)
'()
)
(cond
(
(null? (cdr L))
'()
)
(cons
(car (cdr L))
(second (cdr (cdr L)))
)
)
)
)
Run Code Online (Sandbox Code Playgroud)
但不是我得到的预期结果:
因为(split '(1234))我明白了((1234)()).
因为(first '(1234))我明白了(1234).
因为(second '(1234))我明白了().
有些事情需要考虑:
cond你应该使用的最后一个条件elseif然后a cond,将所有条件放入a中cond,它将使代码更清晰first是错误的,你必须返回一个列表split你应该list用来构建返回的列表,而不是cons{}其他编程语言中的括号 - 这将提高代码的可读性考虑到上述情况,这是一个解决所有问题的实现:
(define split
(lambda (L)
(if (null? L)
'()
(list (first L) (second L)))))
(define first
(lambda (L)
(cond ((null? L) '())
((null? (cdr L)) L)
(else (cons (car L)
(first (cdr (cdr L))))))))
(define second
(lambda (L)
(cond ((null? L) '())
((null? (cdr L)) '())
(else (cons (car (cdr L))
(second (cdr (cdr L))))))))
Run Code Online (Sandbox Code Playgroud)
现在它按预期工作:
(split '(1 2 3 4 5 6 7 8))
=> '((1 3 5 7) (2 4 6 8))
(split '(cat bird dog horse mouse pig tiger gerbil cow))
=> '((cat dog mouse tiger cow) (bird horse pig gerbil))
Run Code Online (Sandbox Code Playgroud)