recursion - 从 Common Lisp 的列表中删除一个元素?

标签 recursion lisp common-lisp

我目前正在尝试从所有级别的列表(递归)中删除我找到的任何 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的carnil
  • 当前单元格的car是一个原子(不为空)
  • 当前cell的car是一个列表

关于 cdr,假设嵌套适当的列表,它将始终是 cons 单元格或 nil

carcdr 是 conses 时,您可能需要对其进行递归。

关于命名:Lisp 阅读器的标准行为是将所有内容大写,因此您显示的名称实际上是 REMOVENILTOPREMOVEALL。约定是编写小写名称,部分用破折号分隔:remove-nil-topremove-all。顺便说一下,我更喜欢 remove-niltree-remove-nil 这两个名字。

关于recursion - 从 Common Lisp 的列表中删除一个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52940592/

相关文章:

c# - 在具有多个表的 Linq 查询中使用递归层次结构树结构并返回一些 Json 值

javascript - 递归中的react.js和传输参数props

lisp - 学习 LISP 的最佳方法是什么?

variables - 通过使用 SETF 定义变量来避免错误

if-statement - 在 Lisp 中有 'eq' 的反义词吗?

memory - 将操作码插入内存

python - 具有循环引用的 __deepcopy__ 对象

c - 为什么这个递归代码会抛出段错误?

Clojure 对比其他 Lisp

不使用标签的 LISP 递归