2017-01-19 7 views
1

не могли бы вы помочь мне решить сложную домашнюю работу о вложенном списке? В принципе в любое время, когда предикат evenp является истинным, я должен удалить элемент из списка (или из вложенного списка), сохраняя структуру всего списка.Как удалить элемент из вложенного списка lisp

(Nopred 'evenp '(1 S d ((4)) (7) ((((8)))) u)) 

Она должна возвращать

(1 S d (()) (7) (((()))) u) 

Это функция, которую я написал

(Defun nopred (f list) 
    (Cond ((null list)) 
     ((Symbolp (car list)) (cons (car list) (nopred f (cdr list))) 
     ((Listp (car list)) (cons (nopred f (car list)) (nopred f (cdr list)))) 
     ((Funcall f (car list)) (nopred f (cdr list))) 
     (T (cons (car list) (nopred f (cdr list)))))) 

Я пытался решить с помощью этого кода, но он не работает, он не удаляет элемент когда evenp истинно и возвращает значения, такие как

((((5 .T) .).).) 
+0

является '(корд л)' копировальные ошибки? Разве это не '(список cdr)'? – Barmar

+0

Когда отступ исправляется, вы можете увидеть проблему. Вам не хватает ')' в конце строки 'Symbolp', поэтому весь этот код рассматривается как часть этого случая. Но это должно вызывать ошибки, поэтому я подозреваю, что это еще одна ошибка копирования. Отправьте фактический код с правильным отступом, иначе мы не сможем сказать, что действительно не так. – Barmar

+0

Особое обращение с символами кажется ошибочным идеологически. Я понимаю, что это нужно, чтобы избежать ошибок в '(evenp S)' & c, но это все еще неправильно. – sds

ответ

0

Вам необходимо вернуть NIL в корпус (null list). Когда у вас нет возвращаемого значения в соответствующем предложении COND, оно возвращает значение условия, а (null list) возвращает T.

У вас также были некоторые опечатки в опубликованном коде: (cdr l) должен был быть (cdr list), а в конце этой строки отсутствовал ).

(defun nopred (f list) 
    (cond ((null list) nil) 
     ((symbolp (car list)) (cons (car list) (nopred f (cdr list)))) 
     ((listp (car list)) (cons (nopred f (car list)) (nopred f (cdr list)))) 
     ((funcall f (car list)) (nopred f (cdr list))) 
     (t (cons (car list) (nopred f (cdr list)))))) 

С этими поправками, которые я получаю правильный результат:

(1 S d (nil) (7) (((nil))) u) 
+0

Спасибо @barmar за ответ, вероятно, я сделал некоторые ошибки, копируя код. (использование смартфонов для написания кодов не так уж и удобно). В любом случае, я думал, что запись cond ((нулевой список) nil) даст (nil) и (((nil))) как конечный результат, который неверен, вместо того, чтобы я должен был получить пустой список, как только предикат evenp будет true , что-то вроде этого (1 S d() (7) ((())) u). Другой вопрос, правильно ли это (funcall f (arg)), насколько я понял, funcall применяет f к arg. Заранее спасибо. – MaxMnt

+0

@MaxMnt '()' и 'nil' - это просто разные способы написания одного и того же объекта, и принтер-получатель будет печатать только один путь. Вам может понадобиться список символов, таких как '' (t nil xy) 'или вы хотите, чтобы списки узлов, некоторые из которых были пустыми' '(t() xy)', однако они одинаковы в терминах 'equal':' (equal '(t nil xy)' (t() xy)); ==> t' – Sylwester

+0

@Sylwester да, я полностью согласен с тем, что вы сказали. но в этом случае результат должен быть с этим представлением ->() вместо Nil. , поэтому выход должен быть -> (1() 3 d (()))) Я попытался заменить Nil на cons (') или append' (() '()), но он не работает. На самом деле это вопрос моего следующего экзамена Lisp в университете, поэтому я ищу способ решить эту проблему с помощью «nil». спасибо. – MaxMnt