LISP检查列表是否对称而没有反转

LISP检查列表是否对称而没有反转,lisp,Lisp,任何人对如何做到这一点有任何想法。。。反转太慢,我想避免使用该函数 基本上,我希望在出现诸如“(abba)或“(abcdcba)之类的内容时能够返回true 对于非对称的事物,如果为false,这不是一个好的解决方案吗?或者你也可以在你最喜欢的搜索引擎中使用“回文lisp”作为关键词来搜索其他解决方案。我不确定为什么使用反向效率不够;你真的分析过这个解决方案吗?只需遍历列表一次即可;与查找列表的长度相同,然后可以遍历两个列表进行比较 如果您想成为一个小爱好者,您可以同时找到列表的长度,并使用循环

任何人对如何做到这一点有任何想法。。。反转太慢,我想避免使用该函数

基本上,我希望在出现诸如“(abba)或“(abcdcba)之类的内容时能够返回true


对于非对称的事物,如果为false,这不是一个好的解决方案吗?或者你也可以在你最喜欢的搜索引擎中使用“回文lisp”作为关键词来搜索其他解决方案。

我不确定为什么使用
反向
效率不够;你真的分析过这个解决方案吗?只需遍历列表一次即可;与查找列表的长度相同,然后可以遍历两个列表进行比较

如果您想成为一个小爱好者,您可以同时找到列表的长度,并使用
循环将其反转,如下所示:

(defun fancier-palindrome-p (list)
  (let ((reversed '()) (length 0)) 
    (dolist (elt list)
      (incf length)
      (push elt reversed)) 
    (dotimes (i (floor length 2) t)
      (unless (eql (pop list) (pop reversed))
        (return nil))))) 
这允许您跳过一半的检查。我认为这不值得增加复杂性。您还可以使用“龟兔下移”来节省一半的时间,但代价是更加复杂

 (defun ridiculous-palindrome-p (list)
   (let ((reversed-front '()))
     (loop  
       :for tortoise :on list 
       :for hare :on list :by #'cddr 
       :until (null (cdr hare)) 
         :do (push (car tortoise) reversed-front)
       :finally  
         (return  
          (if (null hare) ; length is even 
            (equal tortoise reversed-front)
            (equal (cdr tortoise)  
                   reversed-front)))))) 
在我看来,这两种解决方案都不如

(defun palindrome-p (list) (equal list (reverse list))
如果这真的是一个瓶颈,您最好使用向量作为序列表示,以利用快速随机访问,如下所示:

(defun vector-palindrome-p (vector)
  (let* ((n (length vector)) (j n))
    (dotimes (i (floor n 2) (return t))
      (unless (eql (aref vector i) 
                   (aref vector (decf j)))
      (return nil)))))

此功能可避免使用反转:

(defun palindromp (a)
   (or (null a)
       (null (cdr a))
       (and (equal (car a) (car (last a)))
            (palindromp (butlast (cdr a))))))

以下是CommonLisp:

(defun pali (l)
  (labels ((scan (v n l)
             (or (>= n (/ l 2))
                 (and (equal (elt v n) (elt v (- l n 1)))
                      (scan v (+ n 1) l)))))
    (scan (apply #'vector l) 0 (length l))))
您以前是否使用过“
标签”
!?给你(按计划):


这是二次消耗,比反向消耗更糟糕,反向消耗是线性的。我知道:-)但我认为OP要求太多了:使用反向大约是使用链表可以做到的最好的方法。我的回答几乎是一个笑话:是的,它避免了反转,但要付出一定的代价。。。至少我觉得它相当优雅,甚至不用“if”(在宏扩展之前!),这在列表长度上是二次的,而简单的(相等列表(反向列表))是线性的。请不要简单地发布代码。给出一些关于代码的解释、信息或用法。例如,请参见。
(define (palindrome? l)
  (let scanning ((v (list->vector l)) (n 0) (len (length l)))
    (or (>= n (/ len 2))
        (and (equal? (vector-ref v n) (vector-ref v (- len n 1)))
             (scanning v (+ n 1) len)))))
(defun   pal()

(format t "enter list")

(setf list1(read))

(print list1)

(setf list2(rev list1))

(if (equal list1 list2)

(print "palindrome")

(print "not palindrome")))


(reverse (list1)

(setf list2 nil)

(do ((i 1 (+ i 1)))((equal list1 nil)

(format t "reverse list")

(print list2))

(setf list2 (cons (car list1) list2))

(setf list1 ( cdr list1))))