【问题标题】:Remove all nils from a list with sublists in LISP从 LISP 中带有子列表的列表中删除所有 nil
【发布时间】:2016-04-06 21:21:21
【问题描述】:

我有一个包含多个子列表的列表。其中一些具有我需要摆脱的 NIL 元素。我只能使用基本功能(NOT、EQL、CONS 等)

(defun trgni (lista)
  (cond 
    ((null lista) nil)
    ((not (atom (car lista))) (cons (trgni (car lista)) (trgni (cdr lista))))
    ((eql nil (car lista)) (trgni (cdr lista)))
    (t (cons (car lista) (trgni (cdr lista))))))

我的代码有一个问题,当我有一个只包含 nil 的子列表时就会发生这种情况。例如:

(trgni '((NIL ((7))) (8 (9 (10 ((11))) 12)) (13 (NIL NIL))))

我的代码给了我:

((((7))) (8 (9 (10 ((11))) 12)) (13 NIL))

【问题讨论】:

  • "a sublist that contains only nils" 请记住,NIL 空列表,因此((NIL ((7))))((() ((7)))) 相同。
  • @JoshuaTaylor 是的,但问题是它必须打印为 () 而不是 NIL,否则它将无效(作业中的规则)。
  • @Bonne 在 Common Lisp 中,NIL 和空括号 () 是完全相同的两个替代打印拼写:它们指的是 "COMMON-LISP" 包中名为 "NIL" 的符号. (您自己的包中可能有您自己的NIL,这不是COMMON-LISP::NIL 符号;这是一个不同的问题)。 (NIL NIL)(() ())在含义上没有区别。
  • 由于您的目标是学习(而不是真正从树中获取 nils),我想问您是否知道您的代码所采用的路径以便您留下 nil?我愿意。 :) 提示:尝试 (rgni '(13 (nil nil)))。如果您无法通过手动执行代码来解决问题,请使用跟踪或打印语句查看您要去哪里。 hth。 ps:这是非常重要的东西,需要掌握。
  • @kennytilton 好吧,我看到列表即将结束,因为如果列表为空,我告诉它发回NIL,这就是它让我留下(13 NIL) 的原因。但我不知道如何解决这个问题,因为代码中 NIL 的返回对于结束递归本身非常重要。

标签: list null lisp


【解决方案1】:

根据the hyperspec () 只是编写符号nil 的另一种表示法,但是由于它是完全相同的对象,因此CL 在打印时只会使用一种表示法。除非特定实现将其作为可配置功能,否则它不会是替代表示法。

在您的函数中,当您处理car 时,您需要检查结果是否为空。像这样的:

(let ((a (trgni (car lista))))
  (if (null a)
      (trgni (cdr lista))            ; don't include this null value
      (cons a (trgni (cdr lista))))) ; include since it's not null

请注意,这仅适用于像 '(1 (nil nil nil) 2) 这样的嵌套列表,它应该变成 (1 2),但是如果参数是 (nil nil nil) 怎么办?那么它除了nil 之外没有任何合理的价值来评估它,因为nil 是空列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 2014-09-24
    • 1970-01-01
    • 2016-08-26
    相关资源
    最近更新 更多