создание функции lisp, которая дает список четных чисел из списка - PullRequest
0 голосов
/ 04 ноября 2019

Я хотел бы создать функцию для класса, которая будет принимать два аргумента L и L1 в виде списков и помещать все четные числа из L в L1.

Я пробовалв течение нескольких часов, чтобы это заработало, но, к сожалению, я не смог.

Это код моей схемы:

(define (pair L L1)
  (cond
   ((and (not (empty? L)) (= (modulo (first L) 2) 0))
    (begin (append (list (first L)) L1) (pair (rest L) L1)))
   ((and (not (empty? L)) (= (modulo (first L) 2) 1))
    (pair (rest L) L1))
   (else L1)
   ))

1 Ответ

3 голосов
/ 04 ноября 2019

Полагаю, вы хотите использовать L1 в качестве аккумулятора, а в конце вернуть его содержимое.

О вашем коде:

  1. Достаточно проверитьодин раз в первом предложении cond, если L пусто (null?).

  2. append хорошо, если вы хотите добавить список. В вашем случае вы добавляете один элемент, так что cons намного лучше.

  3. Вам не нужно брать modulo числа, чтобы проверить его четность. Существует предикат even?.

Итак, после всех этих соображений ваш код должен выглядеть примерно так:

(define (pair L L1)
  (cond ((null? L) L1)
        ((even? (first L))
         (pair (rest L) (cons (first L) L1)))
        (else (pair (rest L) L1))))

Теперь давайте проверим его:

> (pair '(0 1 2 3 4 5 6 7) '())
(6 4 2 0)

Как видите, он возвращает числа в обратном порядке. Это потому, что когда мы движемся вниз по списку L от головы до хвоста, мы cons вводим новые значения в заголовок (а не в хвост, как append) списка L1. Чтобы исправить это, достаточно (reverse L1) в первом предложении cond вместо простого возврата L1.

Я настоятельно рекомендую "Little Schemer" book. Прочитав его, вы сможете писать любые рекурсивные функции даже во сне;)

...