Мне нужно объединить два списка в схеме, взяв один элемент из каждого

Вот что я написал:

(: mmm : (Listof Any) (Listof Any) -> (Listof Any))
(define (mmm list1 list2)
  (cond [(or (null? list1) (null? list2)) null]
        (and (cons (first list1) (first list2)) (mmm (rest list1) (rest list2)))))

Я приведу вам пример:

list1:  a b c
list2:  1 2 3
answer: ((a 1) (b 2) (c 3))

отредактированы они оба одинакового размера

3 ответа

Решение

Есть несколько проблем с вашим кодом:

  • Базовый случай может быть или не быть правильным - если входные списки гарантированно имеют одинаковый размер, то это нормально. Если они могут быть разного размера, см. Ответ @Sylwester для совета
  • Второе условие должно начинаться с else (потому что это последний и условия являются взаимоисключающими), а не с and
  • Вы неправильно строите список вывода. Добавляемый новый элемент - это список с первым элементом обоих входных списков, который должен быть consв результате вызова рекурсии

Чтобы исправить их, попробуйте это - предполагая, что входные списки равной длины:

(define (mmm list1 list2)
  (cond [(or (null? list1) (null? list2)) null]
        [else (cons (list (first list1) (first list2))
                    (mmm (rest list1) (rest list2)))]))

Теперь процедура работает как положено:

(mmm '(a b c ) '(1 2 3))
=> '((a 1) (b 2) (c 3))

Если вам разрешено использовать map, ты можешь использовать:

(define (mmm lst1 lst2) (map (lambda (x y) (list x y)) lst1 lst2))

If you know the lists are the same size, then it becomes simply:

(define (mmm list1 list2) (map list list1 list2))

Примечание: заменить map list с map cons if that is what you really want. Your code used cons but your result example suggests that list это то, что вы хотите.

Другие вопросы по тегам