【问题标题】:Extracting a list inside a list提取列表中的列表
【发布时间】:2011-04-24 02:10:33
【问题描述】:

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

(defun 删除 (a l) (条件 ((null l) nil) ((eq (car l) a) (删除 a (cdr l))) (t (cons (car l) (delete a (cdr l))))))

它会删除列表 l 中的任何“a”,但如果 l 包含另一个列表并且 a 在该内部列表中,则我的程序无法到达该内部列表。

【问题讨论】:

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

标签: lisp common-lisp


【解决方案1】:

不仅有一种可能的解决方案,但我会密切关注您的代码。由于这是作业,我不会给你一个有效的答案,但我会尽量给你一些思考的东西,并给出详细的指点:

尝试了解您的代码做什么以及您真正希望它做什么:

(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. 如何实现?

我们来看看:

  1. 会发生什么:

    • 列表不是null,继续
    • car 不是 eq1 继续
    • '(1)cons 转换为 (remove-all '()),产生 '((1))

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

  2. 应该怎么做:

    • 检查car 本身是否是一个列表
    • 如果是,请在其上调用remove-all
    • 然后,cons 将结果传递给 cdr,这也需要“清理”(提示:但只有 如果cons 有东西)
  3. 具体是怎样的?

    • 添加一个 cond 子句,该子句执行 2 中提到的事情 -- 留作作业

【讨论】:

    【解决方案2】:

    您需要另一个子句来测试该项目是否为列表,如果为 true,则还递归到子列表中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-15
      • 2020-11-19
      • 2017-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多