【问题标题】:how to remove an element from a nested list lisp如何从嵌套列表lisp中删除元素
【发布时间】:2017-06-03 13:36:15
【问题描述】:

你能帮我解决一个关于嵌套列表的棘手作业吗? 基本上只要谓词 evenp 为 true ,我就应该从列表(或嵌套列表)中删除元素,保持整个列表的结构。

(Nopred 'evenp '(1 S d ((4)) (7) ((((8)))) u))

它应该返回

(1 S d (()) (7) (((()))) u)

这是我写的函数

(Defun nopred (f list)
  (Cond ((null list))
        ((Symbolp (car list)) (cons (car list) (nopred f  (cdr list)))
         ((Listp  (car list)) (cons (nopred f ( car list)) (nopred f (cdr list))))
         ((Funcall f (car list)) (nopred f (cdr list)))
         (T (cons (car list) (nopred f (cdr list))))))

我试图用这段代码解决,但它不起作用,当 evenp 为真时它不会删除元素并且它返回类似

的值
((((5 .T ) .).).) 

【问题讨论】:

  • (cdr l) 是复制错误吗?不应该是(cdr list)吗?
  • 缩进改正后就可以看到问题了。您在Symbolp 行的末尾缺少),因此所有这些代码都被视为该案例的一部分。但这应该会导致错误,所以我怀疑这是另一个复制错误。贴出实际代码,适当缩进,否则我们无法判断真正的错误。
  • 对符号的特殊处理在意识形态上似乎是错误的。我知道这是为了避免(evenp S) &c 上的错误,但这仍然是错误的。
  • 感谢您回答@sds,但我不明白您的意思,情况非常简单明了,如果列表中的元素是符号,那么我放入列表并检查下一个一、上cdr。相反,我不太确定它是否正确 (funcall f (car l)) ,据我所知,它将函数应用于 arg 。谢谢
  • @MaxMnt: 如果你的函数f 在符号上做了一些有趣的事情怎么办? (例如,检查他们的家庭包裹)您的nopred 将不起作用。

标签: lisp common-lisp


【解决方案1】:

您需要在(null list) 的情况下返回NIL。当匹配的COND子句中没有返回值时,它返回条件的值,(null list)返回T

您在发布的代码中还有一些拼写错误:(cdr l) 应该是 (cdr list),而该行末尾缺少 )

(defun nopred (f list)
  (cond ((null list) nil)
        ((symbolp (car list)) (cons (car list) (nopred f  (cdr list))))
        ((listp  (car list)) (cons (nopred f ( car list)) (nopred f (cdr list))))
        ((funcall f (car list)) (nopred f (cdr list)))
        (t (cons (car list) (nopred f (cdr list))))))

通过这些更正,我得到了正确的结果:

(1 S d (nil) (7) (((nil))) u)

【讨论】:

  • 感谢@barmar 的回答,可能我在复制代码时犯了一些错误。 (使用智能手机编写代码并不是那么舒服)。无论如何,我认为编写 cond ( (null list )nil ) 会给出 (nil) 和 (((nil))) 作为最终结果,这是不正确的,而不是一旦谓词 evenp 为真,我应该得到空列表, 所以像这样 ( 1 S d ( ) (7) ((( ))) u) 。另一个问题,对吗 (funcall f (arg)) ,据我所知,funcall 将 f 应用于 arg。提前谢谢你。
  • @MaxMnt ()nil 只是写入同一对象的不同方式,repl 打印机只会以一种方式打印它。您可能想要一个符号列表,例如 '(t nil x y) 或者您想要嵌套列表,其中一些是空的 '(t () x y) 但是这些在 equal 方面是相同的:(equal '(t nil x y) '(t () x y)) ; ==> t
  • @Sylwester 是的,我完全同意你所说的。但在这种情况下,结果必须是这种表示形式 -> () 而不是 Nil。所以输出应该是 -> ( 1 ( ) 3 d ((( ))) ) 我试图用 cons '( ') 或附加 '( ( ) '( ) ) 替换 Nil 但它不起作用。实际上这是我在大学的下一次 Lisp 考试的一种问题,因此我正在寻找一种方法来解决这个问题,用 'nil' 。谢谢。
  • @MaxMnt 没有问题。打印机为nil 显示nil 而不是(),只要您使用该结构,它就会像这样显示它。您可以创建结构的字符串表示或您自己的打印函数,将nil 打印为(),但这只是事物的可视化方式,并没有真正改变不这样做的结果是正确的事实。如果您使用对作为二叉树结构并希望它显示为'((leaf . leaf) . (leaf . leaf)),标准打印机将始终显示为((leaf . leaf) leaf . leaf),则您有相同的效果。
  • @Sylwester 是的,我明白你的意思。事实上,如果是为了我,我会保留现在的代码。但由于这是通过考试的最低要求之一,我仍然想找到输出的解决方案。问题是一切都必须在一个 function 中,所以 print 不能工作那么多,并且在 I would have (list ) 和 nil 作为打印的结果。你能帮我找到解决方案吗?我试图用 ( ) 替换 nil 但它没有,我的意思是我这样做了,但只是作为一个字符串 "( ) ",这在练习中是不允许的。
猜你喜欢
  • 1970-01-01
  • 2021-07-17
  • 2019-07-13
  • 1970-01-01
  • 2017-03-02
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
相关资源
最近更新 更多