Lisp 在列表中提取列表

Lisp 在列表中提取列表,lisp,common-lisp,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) (续) ((空l)无) ((等式(左车)a)(删除a(左车))) (t(cons(左车)(删除a(cdr l()())))) 它删除列表l中的任何“a”,但如果l由另一个

从列表中提取列表时遇到问题

(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) (续) ((空l)无) ((等式(左车)a)(删除a(左车))) (t(cons(左车)(删除a(cdr l()()))))
它删除列表l中的任何“a”,但如果l由另一个列表组成,而a在该内部列表中,则我的程序无法到达该内部列表。

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

不仅有一个可能的解决方案,但我会继续关注你的代码。由于这是作业,我不会给你一个有效的答案,但我会尝试给你一些思考的东西,并给出详细的提示:

试着理解你的代码是做什么的,以及你真正想要它做什么:

(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'((1)))
    ,会发生什么情况
  • 对于该输入,您希望发生什么
  • 你怎样才能做到呢
  • 我们来看看,

  • 发生了什么:

    • 列表不为空,请继续
    • car
      没有
      eq
      1
      继续
    • ”(1)
      cons
      编辑为
      (删除所有“())
      ,生成
      ”((1))
    因此,它没有认识到
    汽车
    本身就是一个应该搜索匹配元素的列表。问题似乎在第一步和第二步之间

  • 应该做什么:

    • 如果
      汽车
      本身就是一个列表,请进行检查
    • 如果是,则调用
      删除其上的所有
    • 然后,
      cons
      将结果发送到
      cdr
      ,cdr也需要“清理”(提示:但只有在
      cons
      有内容时)
  • 到底是怎么回事

    • 添加一个
      cond
      子句,该子句完成第2项中提到的事情——留作家庭作业

  • 不要将函数命名为DELETE。Common Lisp已经为内置函数使用了该名称。默认的相等性测试也应该是EQL,而不是EQ。