0

我有一个工作回文,它通过将汽车与反向汽车进行比较,为带有原子的单个列表返回真/假。然后它用 cdr (reverse (cdr list)) 丢弃第一个和最后一个。

我想让它与子列表中的原子一起使用,以便 '(ab) c (ba)) 返回 true。

我试图让它首先检查 car 是否是一个列表,如果是,比较 caar 和 reverse caar 直到它为空,然后继续。
我收到“对象#f 不适用”。

(DEFINE (pdrome lst)
  (cond
    ; ((NOT (LIST? lst)) DISPLAY "USAGE: (palindrome [list])" )
    ((null? lst) #t)
     ((null? (cdr lst)) #t)

     ((LIST? (car lst))
       ((null? (car lst) ) () )
       ((null? (cdr lst) ) () )
    ((equal? (caar lst) (caar (reverse lst)))
    (pdrome (cdar (reverse(cdar lst))))))

     ((equal? (car lst) (car(reverse lst))) 
      (pdrome (cdr (reverse (cdr lst)))))

        (else #F) ) )

我也尝试过这样做,这样它就不会嵌套,但我无法弄清楚。任何提示或提示表示赞赏。谢谢!

(LIST? car lst)  
palindrome (append (caar lst) (caar (reverse lst)))
4

2 回答 2

1

这是您的代码,正确缩进:

(DEFINE (pdrome lst)
  (cond
   ((null? lst) #t)
   ((null? (cdr lst)) #t)
   ((LIST? (car lst))
    ((null? (car lst))())
    ((null? (cdr lst))())
    ((equal? (caar lst) (caar (reverse lst)))
     (pdrome (cdar (reverse(cdar lst))))))
   ((equal? (car lst) (car(reverse lst))) 
    (pdrome (cdr (reverse (cdr lst)))))
   (else #F)))

请注意第三个子句在应该结束的时候没有结束?或者您可能在检查之前尝试检查几个条件(equal? (caar lst) (caar (reverse lst)))

当您调用 时(pdrome '((a b) c (b a))),它会到达为真的地步(LIST? (car lst)),因此它会评估该子句中的其余代码。那是:

    ((null? (car lst))())
    ((null? (cdr lst))())
    ((equal? (caar lst) (caar (reverse lst))

我们来看第一个:((null? (car lst))()). 如何评估?这是一个包含两个元素的列表,因此请评估第一个元素:(null? (car lst)). 评估为#F。然后,我们有(#F ()). #F处于功能位置(列表中的第一件事被评估为代码),但不是功能。所以我们得到了错误Object #f is not applicable

基本上,cond的每个子句如下所示:

(condition form1 form2 ...)

可以有任意数量的形式,包括零。

所以让我们看看你的单子句

((LIST? (car lst))
 ((null? (car lst))())
 ((null? (cdr lst))())
 ((equal? (caar lst) (caar (reverse lst)))
  (pdrome (cdar (reverse(cdar lst))))))

这是条件:

(LIST? (car lst))

这是表格。其中有三个:

 ((null? (car lst))())
 ((null? (cdr lst))())
 ((equal? (caar lst) (caar (reverse lst)))
  (pdrome (cdar (reverse(cdar lst))))))

如果条件为真(也就是说,(car lst)它本身就是一个列表),那么你想做什么?

我将退后一分钟,按照我手动的方式布置算法。

直到我们没有列表了,剪掉第一件事,最后一件,看看第一件和最后一件是不是一样。如果这些东西本身是列表,请反转最后一个。然后继续在列表的中间(即没有第一个或最后一个元素的列表)执行此操作,直到我们最终得到一个空列表或只有一个东西的列表。

现在让我们编写一些代码:

(define (palindrome lst)
  (if (null? lst)
      #t
      (let ((first-element (car lst))
            (last-element (car (reverse lst))))
        (and (equal? first-element
                     (if (list? last-element)
                         (reverse last-element)
                         last-element))
             (palindrome (get-middle lst))))))

(define (get-middle lst)
  (if (null? (cdr lst))
      '()
      (reverse (cdr (reverse (cdr lst))))))

> (palindrome '())
#t
> (palindrome '(a))
#t
> (palindrome '((a)))
#t
> (palindrome '((a) b))
#f
> (palindrome '((a) b (a)))
#t
> (palindrome '((a b) c (b a)))
#t  

请注意,此代码与编写的算法略有不同。当它到达一个包含一个元素的列表时(例如,它被称为(palindrome '(a)),它将获取第一个元素'a,最后一个元素'a,确保它们相等,然后调用(get-middle '(a)),即'()。然后(palindrome '())#f,所以我们很好。

于 2013-11-01T23:39:23.620 回答
0

最简单的方法是使用深度反向过程,该过程将递归地反转列表。

(define (deep-reverse l) 
  (if (list? l) 
      (reverse (map deep-reverse l)) 
      l))

查看它与内置反向的比较:

-> (reverse '((a b) c (d e)))
'((d e) c (a b))
-> (deep-reverse '((a b) c (d e)))
'((e d) c (b a))

所以回文只是一个相等的列表?到它的深度反转:

(define (pdrome? lst)
  (equal? lst (deep-reverse lst)))
于 2013-11-01T22:55:12.047 回答