使用append同时处理2个列表

时间:2010-12-27 04:26:01

标签: scheme racket

我从HTDP.坚持练习17.1.2的问题这是我到目前为止所做的:

(define (cross alist1 alist2)
  (cond
    [(empty? alist1) empty]
    [else (append (list (first alist1)(first alist2))
                  (cons (first alist1)(list (first (rest alist2))))
                  (cross (rest alist1) alist2))]))

(cross '(a b c) '(1 2))
;correctly outputs (list 'a 1 'a 2 'b 1 'b 2 'c 1 'c 2)

这适用于测试用例,但是当第二个列表包含2个以上的元素时,该函数就会崩溃。

(cross '(a b c) '(1 2 3))
;outputs (list 'a 1 'a 2 'b 1 'b 2 'c 1 'c 2)

这个问题似乎是追加后的第二行,因为它只会占用第二个列表中的两个元素。我该如何解决这个问题?感谢您的任何见解。 :)

1 个答案:

答案 0 :(得分:2)

它仅适用于列表2中的两个元素,因为您只指定它用于列表2中的两个元素。我们需要利用抽象的力量。

如果我们使用命令式语言,那么我们就会在这个问题上使用嵌套的for循环。你从alist1的第一个元素开始,并与alist2的所有元素匹配。然后你转到alist1的第二个元素并匹配alist2的所有元素。由于我们使用的是函数式语言(Scheme),我们将使用嵌套函数而不是嵌套的for循环。

你想写一个函数,它取'a和'(1 2 3)并产生'(a 1 a 2 a 3),然后另一个函数调用第一个具有不同值'a'的函数。如果您不希望下面的解决方案破坏您应该忽略的相关代码。

(define (cross alist1 alist2)
 (cond
  ((null? alist1) '())
  (else 
   (append (innercross (car alist1) alist2)
           (cross (cdr alist1) alist2)))))

(define (innercross a1 alist2)
 (cond
  ((null? alist2) '())
  (else
   (cons a1 (cons (car alist2) (innercross a1 (cdr alist2)))))))