Существует не только одно возможное решение, но я останусь рядом с вашим кодом. Поскольку это домашнее задание, я не дам вам рабочего ответа, но постараюсь дать вам некоторые соображения и дать подробные указания:
Постарайтесь понять, что делает ваш код и что вы действительно хотите от него:
(defun remove-all (a l)
(cond ((null l) nil)
((eql (car l) a) (delete a (cdr l)))
(t (cons (car l) (delete a (cdr l))))))
(Переименовано в remove-all
, потому что delete
уже занято и перемаркировано в разумной манере.)
Для плоских списков код работает; а как насчет вложенных списков? Давайте посмотрим на простой пример:
- Что будет, если вы оцените
(remove-all 1 '((1)))
?
- Что вы хотите, чтобы произошло с этим входом?
- Как этого добиться?
Давайте посмотрим:
Что происходит:
- Список не
null
, продолжайте
-
car
не eq
до 1
иди
'(1)
получает cons
ed до (remove-all '())
, получая '((1))
Таким образом, он не смог распознать, что car
сам по себе является списком, в котором следует искать соответствующие элементы. Кажется, что проблема лежит между первым и вторым шагом.
Что нужно сделать:
- Проверьте, является ли
car
списком
- Если да, вызвать
remove-all
на нем
- Затем
cons
результат для cdr
, который также необходимо «очистить» (Подсказка: но только , если есть что-то для cons
)
Как именно?
- Добавить предложение
cond
, которое выполняет вещи, упомянутые в пункте 2 - Оставлено как домашнее задание