2016-04-06 3 views
1

У меня есть список с несколькими подсписками. Некоторые из них имеют элементы NIL, от которых мне нужно избавиться. Я могу использовать только основные функции (NOT, EQL, СВОД и т.д ..)Удалить все нули из списка с подсписками в LISP

(defun trgni (lista) 
    (cond 
    ((null lista) nil) 
    ((not (atom (car lista))) (cons (trgni (car lista)) (trgni (cdr lista)))) 
    ((eql nil (car lista)) (trgni (cdr lista))) 
    (t (cons (car lista) (trgni (cdr lista)))))) 

У меня есть одна проблема с моим кодом, и это происходит, когда у меня есть подсписок, который содержит только Нильс. Например:

(trgni '((NIL ((7))) (8 (9 (10 ((11))) 12)) (13 (NIL NIL)))) 

мой код дает мне:

((((7))) (8 (9 (10 ((11))) 12)) (13 NIL)) 
+0

«подсписок, содержащий только нули». Помните, что NIL * - это пустой список, поэтому '((NIL ((7))))', например, совпадает с '((() ((7)))) '. –

+0

@JoshuaTaylor Да, но проблема в том, что он должен быть напечатан как() вместо NIL, иначе он не будет действителен (правила из домашней работы). – Bonne

+0

@Bonne В Common Lisp, 'NIL' и пустые круглые скобки'() 'являются двумя альтернативными печатными надписями для одного и того же: они ссылаются на символ под названием' 'NIL' 'в пакете' 'COMMON-LISP '' , (Возможно, у вас есть собственный 'NIL' в вашем собственном пакете, который не является символом COMMON-LISP :: NIL, это другая проблема). Нет никакой разницы в значении между '(NIL NIL)' и '(()())'. – Kaz

ответ

1

Согласно the hyperspec() это просто альтернатива обозначения для написания символа nil, однако, так как это тот же самый объект CL будет использовать только одно обозначение при печати. Это не будет альтернативной нотацией, если конкретная реализация не будет ее настраиваемой функцией.

В вашей функции, когда вы обрабатываете car, вам нужно проверить, пуст ли результат. Что-то вроде этого:

(let ((a (trgni (car lista)))) 
    (if (null a) 
     (trgni (cdr lista))   ; don't include this null value 
     (cons a (trgni (cdr lista))))) ; include since it's not null 

Обратите внимание, что это работает только для вложенных списков, как '(1 (nil nil nil) 2), который должен стать (1 2), но что, если аргумент (nil nil nil)? Тогда он не будет иметь никакого разумного значения, кроме nil, чтобы оценить его как nil - это пустой список.

Смежные вопросы