提取列表中的列表

时间:2010-10-12 01:30:10

标签: lisp common-lisp

我在从列表中提取列表时遇到问题。

(defun delete (a l)
    (cond
       ((null l) nil)
       ((eq (car l) a) (delete a (cdr l)))
       (t (cons (car l) (delete a (cdr l))))))

它会删除列表中的'a',但是如果l由另一个列表组成,并且a在该内部列表中,则我的程序无法到达该内部列表内。

2 个答案:

答案 0 :(得分:5)

不仅有一种可能的解决方案,而且我会保持接近您的代码。由于这是作业,我不会给你一个有效的答案,但我会尽量给你一些思考的东西,并给出详细的指示:

尝试了解代码的作用以及您真正希望它执行的操作:

(defun remove-all (a l)
  (cond ((null l) nil)
        ((eql (car l) a) (delete a (cdr l)))
        (t (cons (car l) (delete a (cdr l))))))

(已重命名为remove-all,因为delete已被占用,并以理智的方式重新缩进。)

对于平面列表,代码似乎有效;但嵌套列表怎么样?让我们看一个简单的例子:

  1. 如果您评估(remove-all 1 '((1)))会怎样?
  2. 您希望该输入发生什么?
  3. 你怎么能实现它?
  4. 我们来看看:

    1. 会发生什么:

      • 列表不是null,请继续
      • car不是eq1继续
      • '(1)获得cons (remove-all '())'((1))

      因此,它未能认识到car本身就是一个应该搜索匹配元素的列表。问题似乎在第一步和第二步之间。

    2. 应该做什么:

      • 检查car本身是否为列表
      • 如果是,请在其上调用remove-all
      • 然后,cons将结果发送到cdr,这也需要“清理”(提示:但只有,如果有某些内容要cons
    3. 到底是怎么回事?

      • 添加一个cond子句,该子句执行2 - 左侧作为家庭作业
      • 中提到的内容

答案 1 :(得分:3)

您需要另一个子句来测试该项是否为列表,而当为true时,还需要递归到子列表中。