我正在学习方案,我要做的一件事就是递归,以确定列表是否具有反射性,即列表在反转时看起来是一样的。我必须原始这样做,所以我不能使用反向方法列表。我还必须使用明显的递归。问题是在方案中,使用我们学到的非常基本的东西很难访问列表或缩短列表,因为它们有点像链接列表。我也想不使用索引。 有了这个说我有一些想法,并想知道如果这些充足,你认为我可以用方案的基础知识做得更好。
答案 0 :(得分:3)
检查列表是否为回文而不反转是"There and Back Again" by Danvy and Goldberg中解释的技术示例之一。他们在(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) ....)
这听起来像是家庭作业,所以我不想填写所有的空白。
答案 1 :(得分:2)
我同意#1似乎是去这里的方式。它很简单,我无法想象它失败了。也许我没有足够强大的想象力。 :)
您正在考虑的其他选项看起来很尴尬,因为我们讨论的是链接列表,它直接支持顺序访问,但不支持随机访问。如您所知,“索引”到链接列表是禁止的。它最终在列表结构中尽职尽责地进行游行。因此,其他选择肯定是可行的,但它们很昂贵。
这笔费用不是因为我们在Scheme中:这是因为我们正在处理链接列表。只是为了确保它是清楚的:Scheme具有支持快速随机访问的向量(数组)。在矢量上测试回文就像你期望的那样容易:
#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的方法要求对表示进行彻底改变:从第一眼看,我认为你是需要可变的,双链表来解决任何正义,因为你需要能够向后行进。
答案 2 :(得分:0)
要回答dyoo的问题,你不必知道你处于中间位置;你只需要进行一定的比较。如果这种比较有效,那么a)字符串必须是可逆的,b)你必须处于中间点。
如果能够达到目的,那么就会有更有效的解决方案......