Удалить элемент из списка в Common Lisp? - PullRequest
0 голосов
/ 23 октября 2018

В настоящее время я пытаюсь удалить любой NIL, который я найду из списка (рекурсивно) на всех уровнях.Я уже знаю, как удалить NIL из верхнего уровня списка, и я думал, что большая часть идеи будет одинаковой при работе с несколькими уровнями, однако я столкнулся с загадкой.

Мой код дляудаление Nil с верхнего уровня:

(defun removeNILTop (L)
    (cond ( (NULL L) NIL) ;;list is empty
          ( (NULL (CAR L)) (removeNILTop( CDR L))) ;;Nil so skip it
          ( T (CONS( CAR L) (removeNILTop( CDR L)))) ;;not NIL so include it
    )
)

Это мой код для удаления Nil со всех уровней:

  (defun removeAll (l)
        (cond
            ((null l) NIL) ;;empty list
            ((null (car l)) (removeAll(cdr l))) ;;Nil so skip it
            ((atom (car l)) (cons (car l) (removeAll(cdr l)))) ;;not nil and is a atom so continue normally
            (T (cons( removeAll(car l) (removeAll(cdr l))))) ;;car is a list recurse into it
        )

    )

То, как я думал об этом, заключается в том, что в первом примере я игнорируюкакая машина из списка и просто держите ее, пока она не равна нулю.Тем не менее, теперь, когда я забочусь об этом, я должен проверить, является ли автомобиль

  • атомом, а не нолем, если это так, то я могу нормально продолжить
  • в противном случае, если этосписок, который я должен добавить в него, и довести результат до результата cdr.

Это, очевидно, не работает, какие-либо советы?

Ответы [ 2 ]

0 голосов
/ 23 октября 2018
(defun removeAll (l)
  (cond ((null l) NIL)
        ((null (car l)) (removeAll(cdr l))) 
        ((atom (car l)) (cons (car l) (removeAll (cdr l)))) 
        (T (cons (removeAll (car l)) (removeAll (cdr l))))))

Вы забыли закрыть в последнем предложении первый removeAll на (car l) с помощью парентеза.

Вы можете избежать таких ошибок, используя редактор, который поддерживает автоматическое заполнение паратеза.И отступ кода автоматически.Какой редактор вы используете?

0 голосов
/ 23 октября 2018

У вас есть три дела относительно car сейчас.Глядя на это с точки зрения текущей ячейки:

  • car текущей ячейки равно nil
  • car текущей ячейки - это атом (а не NULL)
  • car текущей ячейки является списком

Что касается cdr, при условии, что вложенные правильные списки всегда будут либо cons-ячейкой, либоnil.

Возможно, вам придется повторяться на car и cdr, когда они являются консусами.

Относительно именования: стандартное поведение считывателя Лиспа состоит в том, чтобы все портить, поэтомуимена, которые вы показываете, на самом деле REMOVENILTOP и REMOVEALL.Соглашение заключается в написании строчных имен с частями, разделенными черточками: remove-nil-top, remove-all.Кстати, мне нравятся имена remove-nil и tree-remove-nil.

...