Обработка 2 списков одновременно с помощью добавления - PullRequest
2 голосов
/ 27 декабря 2010

Я застрял в вопросе к Упражнению 17.1.2 из HTDP. Это то, что я до сих пор получил:

(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 Ответ

2 голосов
/ 27 декабря 2010

Он работает только для двух элементов в списке два, потому что вы указали его только для двух элементов в списке два. Нам нужно использовать силу абстракции.

Если бы мы работали на императивных языках, то для этой проблемы мы использовали бы вложенные циклы for. Вы начинаете с первого элемента alist1 и сопоставляете его со всеми элементами alist2. Затем вы переходите ко второму элементу alist1 и сопоставляете его со всеми элементами alist2. Поскольку мы работаем на функциональном языке (схема), мы будем использовать вложенные функции вместо вложенных циклов 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)))))))
...