0

我写了两个程序,一个是 takeoutAllButLast,另一个是 takeoutSecondLast。

我最初使用成员函数来确定后面是否还有更多的X。

我尝试了一些数据并发现:

如果第一个参数是符号,它们都有效!

但如果是 cons 结构,它们都会失败。

1.// `(a b)   `((b b)(a b)(b c)(a b)) ==>  `((b b)(b c)(a b)) 

(defun takeoutAllButLast (X L)
(cond ((null L) nil)
       ((equal X (first L)) 
           (if (member X (rest L)) 
               (takeoutAllButLast X (rest L)) 
               L)) 
       (t (cons (first L) (takeoutAllButLast X (rest L))))
)
)

2.//`(a b)   `((a b)(b b)(a b)(b c)(a b)) ==>  `((a b)(b b)(b c)(a b)) 
(defun takeoutSecondLast (X L)
(cond ((null L) nil)
       ((equal X (first L)) 
           (if (member X (rest (member X (rest L))))
    (cons (first L) (takeoutSecondLast X (rest L)))
    (rest L)
           )
    )
   (t (cons (first L) (takeoutSecondLast X (rest L))))
 )

我想问的是如何判断后面是否还有一个元素是X,可以像成员函数一样使用吗?

为什么不能使用成员函数来比较 cons 结构?

谢谢你阅读我的问题!

4

1 回答 1

2

member默认使用eql作为它的相等谓词。这适用于符号、数字和其他一些东西((eq 'a 'a)总是正确的,(let ((cons (cons 'a 'a))) (eql cons cons))总是正确的,但(eql (cons 'a 'a) (cons 'a 'a))几乎永远不会正确)。

你可以通过一个替代的相等检查器来member使用:test关键字,如果你使用#'equal你会(可能)得到你想要的。

如果您想member使用自定义相等检查器调用foo,只需执行以下操作:

(member thing-to-check-for the-list-to-check :test #'foo)
于 2012-10-11T14:34:40.390 回答