Recursion 检查列表的反面是否与未更改的列表相同?

Recursion 检查列表的反面是否与未更改的列表相同?,recursion,scheme,racket,reverse,Recursion,Scheme,Racket,Reverse,我正在学习scheme,我必须做的一件事是递归,以确定列表是否具有反射性,即列表在反转时看起来是相同的。我必须以基本的方式来做,这样我就不能对列表使用反向方法。我还必须使用递归,这是显而易见的。问题是在scheme中,使用我们所学的非常基本的东西很难访问列表或缩短列表,因为它们有点像LinkedList。我也不想使用索引。 话虽如此,我有一些想法,想知道这些想法是否足够,你认为我是否可以用scheme的基本知识做得更好 使用递归(我的实现)反转列表,并比较原始版本和此版本。名单 通过递归列表的其

我正在学习scheme,我必须做的一件事是递归,以确定列表是否具有反射性,即列表在反转时看起来是相同的。我必须以基本的方式来做,这样我就不能对列表使用反向方法。我还必须使用递归,这是显而易见的。问题是在scheme中,使用我们所学的非常基本的东西很难访问列表或缩短列表,因为它们有点像LinkedList。我也不想使用索引。 话虽如此,我有一些想法,想知道这些想法是否足够,你认为我是否可以用scheme的基本知识做得更好

  • 使用递归(我的实现)反转列表,并比较原始版本和此版本。名单
  • 通过递归列表的其余部分来比较第一个和最后一个元素,找到最后一个元素并与第一个元素进行比较。跟踪我递归了多少次,然后对列表的第二个最后一个元素少做一次,以与列表的第二个元素进行比较。(这是非常复杂的,因为我已经尝试过了,但最终失败了,但我希望你们也会这么做)
  • 缩短列表以每次修剪第一个和最后一个元素并进行比较。我不确定是否可以使用scheme的基础知识来实现这一点
  • 你的建议、暗示或其他什么。我对这个计划很陌生。谢谢你的阅读。我知道它很长
  • 我同意#1在这里似乎是正确的选择。这很简单,我无法想象它会失败。也许我没有足够的想象力

    您正在考虑的其他选项似乎有些尴尬,因为我们讨论的是链表,它直接支持顺序访问,但不支持随机访问。正如您所注意到的,链接列表中的“索引”是多余的。它最终尽职尽责地沿着列表结构行进。正因为如此,其他选择当然是可行的,但代价高昂

    这并不是因为我们在计划中,而是因为我们在处理链表。为了确保清楚:该方案有支持快速随机访问的向量(数组)。测试向量上的回文性与您预期的一样简单:

    #lang racket
    ;; In Professional-level Racket
    
    (define (palindrome? vec)
      (for/and ([i (in-range 0 (vector-length vec))]
                [j (in-range (sub1 (vector-length vec)) -1 -1)])
        (equal? (vector-ref vec i)
                (vector-ref vec j))))
    
    ;; Examples
    (palindrome? (vector "b" "a" "n" "a" "n" "a"))
    (palindrome? (vector "a" "b" "b" "a"))
    
    因此,我认为,您要解决的问题的一点是,显示您选择的数据结构——问题的表示形式——可以对问题解决方案产生强大的影响


    (旁白:#2当然是可行的,尽管它与单链表数据结构的粒度相反。实现#3的方法需要对表示方式进行根本性的更改:乍一看,我认为您需要可变的、双链接的列表来实现解决方案,因为您需要能够向后移动。)要回答dyoo的问题,你不必知道自己已经到了一半;你只需要做一个比较。如果这种比较有效,那么a)字符串必须是可逆的,b)必须在中间点


    因此,如果您可以直接找到更有效的解决方案…

    检查列表是否是回文而不反转它是中介绍的技术示例之一。它们在
    (ceil(/(length-lst)2))递归调用中实现,但有一个更简单的版本在
    (length-lst)
    调用中实现

    以下是解决方案的框架:

    (define (pal? orig-lst)
      ;; pal* : list -> list/#f
      ;; If lst contains the first N elements of orig-lst in reverse order,
      ;; where N = (length lst), returns the Nth tail of orig-lst.
      ;; Otherwise, returns #f to indicate orig-lst cannot be a palindrome.
      (define (pal* lst)
        ....)
    
      .... (pal* orig-lst) ....)
    

    这听起来像是家庭作业,所以我不想填所有的空白。

    谢谢你的回答。我想我已经做了决定,我会选择第一名。这是最简单的,尽管我关心的是效率。一个修改是,我取下列表的下半部分,将其颠倒过来,并与上半部分进行比较。这么多乏味的工作啊!你提议的修改的问题是:你怎么知道你已经到了一半了是 啊这就是为什么我说了这么多乏味的工作,因为现在我必须找到列表的长度并除以2,然后递归列表很多次,得到列表的后半部分。然后倒转列表,然后与上半部分进行比较。天哪,一定有更简单的办法(我对scheme也是新手……我只是想知道“pal?”“pal”和“pal”之间的区别是什么。