Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 为什么我的lisp函数返回';无';_List_Lisp_Common Lisp_Clisp - Fatal编程技术网

List 为什么我的lisp函数返回';无';

List 为什么我的lisp函数返回';无';,list,lisp,common-lisp,clisp,List,Lisp,Common Lisp,Clisp,我正在编写一个lisp函数,它将确定一个单词是否是回文,而不使用“reverse”函数。我对lisp还相当陌生,我仍在努力掌握这个概念。每次我测试回文时,函数都返回NIL,你知道为什么吗 我提出的功能 (defun palindromep (list) (cond ((null list)t) (t (and (equal (first list) (first (rest list))) (pali

我正在编写一个lisp函数,它将确定一个单词是否是回文,而不使用“reverse”函数。我对lisp还相当陌生,我仍在努力掌握这个概念。每次我测试回文时,函数都返回
NIL
,你知道为什么吗

我提出的功能

(defun palindromep (list)
    (cond
        ((null list)t)
        (t
            (and (equal (first list) (first (rest list)))
                (palindromep (butlast (rest list)))))))
代码修订

(defun palindromep (list)
    (cond
        ((null list)t)
        (t
            (and (equal (first list) (first(last list)))
                (palindromep (butlast(rest list)))))))

在我看来,它似乎在一组特殊的回文中起作用,其中有偶数个相同类型的元素

对于一个元素列表,您需要返回
t
。即
(空(cdr列表))

您进行的检查将检查前两个元素是否相同,而不是第一个元素和最后一个元素是否相同

编辑

我能想到的使用递归和不使用反向的最好方法是:

(defun palindromep (list)
  (labels ((aux (history tortoise hare)
             (cond ((null hare) (equal tortoise history))
                   ((null (cdr hare)) (equal (cdr tortoise) history))
                   (t (aux (cons (car tortoise) history)
                           (cdr tortoise)
                           (cddr hare))))))
    (aux '() list list)))
它的工作原理是有一个额外的光标
hare
,该光标的迭代距离是
tortoise
的两倍,同时所看到的元素在
历史中积累。由于
cons
从头到尾创建列表,因此历史记录是所有看到的元素的相反方向,因此当您到达中间位置时,应该与末尾相匹配。当hare的
cdr
cddr
为空时,您处于中间位置,可以通过简单的比较确定回文

编辑2

如果将辅助对象移出,则更容易跟踪和查看发生的情况:

(defun aux (history tortoise hare)
  (cond ((null hare) (equal tortoise history))
        ((null (cdr hare)) (equal (cdr tortoise) history))
        (t (aux (cons (car tortoise) history)
                (cdr tortoise)
                (cddr hare)))))

(defun palindromep (list)
  ;; just calls helper
  (aux '() list list))

;; trace the helper
(trace aux)
(trace equal) ; you might need to follow instructions to unlock

(palindromep '(1 2 3 3 2 1))
  0: (AUX NIL (1 2 3 3 2 1) (1 2 3 3 2 1))
    1: (AUX (1) (2 3 3 2 1) (3 3 2 1))
      2: (AUX (2 1) (3 3 2 1) (2 1))
        3: (AUX (3 2 1) (3 2 1) NIL)
          4: (EQUAL (3 2 1) (3 2 1))
          4: EQUAL returned T
        3: AUX returned T
      2: AUX returned T
    1: AUX returned T
  0: AUX returned T
==> T

(palindromep '(1 2 3 4 5 6))
  0: (AUX NIL (1 2 3 4 5 6) (1 2 3 4 5 6))
    1: (AUX (1) (2 3 4 5 6) (3 4 5 6))
      2: (AUX (2 1) (3 4 5 6) (5 6))
        3: (AUX (3 2 1) (4 5 6) NIL)
          4: (EQUAL (4 5 6) (3 2 1))
          4: EQUAL returned NIL
        3: AUX returned NIL
      2: AUX returned NIL
    1: AUX returned NIL
  0: AUX returned NIL
==> NIL

我修改了我的代码,现在它告诉我,我输入的每一个东西都是回文,有什么建议吗?@RileyThomas,这是因为递归的参数是正确的,但现在不是了。递归不再只在第一个元素出现时才执行,而是一直执行,直到达到基本情况,即空列表。此外,一个元素列表的测试应该与空列表的测试一起进行<代码>(或a b)
或作为
条件中的单独术语
。现在它是如何做的它总是在默认情况下,而不是作为一个尾部表达式。我所做的修订似乎现在工作。关于如何重写函数的最后一行,使其仍能执行相同的操作,有什么建议吗?@RileyThomas似乎默认情况是可以的。您需要检查
(或(null列表)(null(cdr列表)))
而不仅仅是
(null列表)
,它也适用于奇数元素回文。既然您只有两个术语if,那么if与
if也同样适用,那么我将包括这两个术语,还有没有其他方法可以说
(回文(但最后一个(rest list))