我目前正在尝试从所有级别的列表(递归)中删除我找到的任何 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
)
)
我的想法是,在第一个示例中,我忽略了列表中的汽车,只要它不为空就保留它。不过,既然关心了,就该看看车是不是了
- 一个原子而不是 nil,如果它是那么我可以正常进行
- 否则,如果它是一个列表,那么我应该对其进行递归,并将结果转换为 cdr 的结果。
这显然是行不通的,有什么提示吗?
最佳答案
你现在有三个关于汽车
的案例。从当前cell的角度来看:
- 当前cell的
car
为nil
- 当前单元格的
car
是一个原子(不为空) - 当前cell的
car
是一个列表
关于 cdr
,假设嵌套适当的列表,它将始终是 cons 单元格或 nil
。
当 car
和 cdr
是 conses 时,您可能需要对其进行递归。
关于命名:Lisp 阅读器的标准行为是将所有内容大写,因此您显示的名称实际上是 REMOVENILTOP
和 REMOVEALL
。约定是编写小写名称,部分用破折号分隔:remove-nil-top
、remove-all
。顺便说一下,我更喜欢 remove-nil
和 tree-remove-nil
这两个名字。
关于recursion - 从 Common Lisp 的列表中删除一个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52940592/