【问题标题】:How to run this lisp functional programming code?如何运行这个 lisp 函数式编程代码?
【发布时间】:2020-07-15 04:15:57
【问题描述】:

我正在尝试运行此代码,该代码据称会从已排序的数字列表中删除重复项。

    (defun unique (x)
(cond( (null x) x )
( (null (cdr x)) x )( (equal (car x) (cdr x)) (unique (cdr x)) )( t (cons (car x) (unique (cdr x))) )))

我正在尝试通过键入以下内容来调用此函数:

(print (unique '(2 2 3 4 4 5)))

我的输出目前显示如下:

(2 2 3 4 4 5)

显然,这似乎并没有删除重复项,如果有的话。

【问题讨论】:

    标签: functional-programming lisp common-lisp


    【解决方案1】:

    表单中有错误:(equal (car x) (cdr x))car返回列表的第一个元素,而cdr返回列表的其余部分,所以比较的不是列表的第一个和第二个元素,而是第一个元素和没有第一个元素的列表(对于常规列表,这种比较总是会产生错误)。

    要更正错误,函数应使用cadr 而不是cdr(equal (car x) (cadr x)):函数cadr(或其同义词second)等价于car (cdr,并返回第二个元素一个列表。所以这是正确的版本:

    CL-USER> (defun unique (x)
               (cond ( (null x) x )
                     ( (null (cdr x)) x ) 
                     ( (equal (car x) (cadr x)) (unique (cdr x)) )
                     ( t (cons (car x) (unique (cdr x))) )))
    UNIQUE
    CL-USER> (unique '(1 1 2 2 3))
    (1 2 3)
    

    【讨论】:

    • “这个比较总是会产生错误”这需要一个反例:-)考虑(let* ((tail (list 0 1 2)) (list (cons tail tail))) (assert (equal (car list) (cdr list))))
    • 是的,另一个反例是(1 . 1) :)。我省略了“常规列表”。已更正,谢谢@coredump。
    • 看起来这不适用于测试用例 (print (unique '(2))) (print (unique '(2 2 3 4 4 5))),因为它不会删除额外 4
    • @Greg,它对我有用:(unique '(2 2 3 4 4 5)) 产生 (2 3 4 5)。你在哪个系统上测试过?
    猜你喜欢
    • 1970-01-01
    • 2020-06-04
    • 1970-01-01
    • 2012-01-04
    • 2013-07-25
    • 2017-10-31
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    相关资源
    最近更新 更多