Recursion 算术递归
我是scheme的初学者,我正在尝试学习一些算术递归。我似乎无法用计划来完成这项工作并产生正确的结果。例如,我试图通过对字符串中的每个字符进行算术运算来为字符串生成一个整数键。在本例中,字符串是一个列表,例如:'(h e l o)。我需要执行的算术是: 对于字符串中的每个字符do-->(33*常量+字母表中字母的位置) 其中常量为输入,字符串作为列表输入 到目前为止,我有:Recursion 算术递归,recursion,scheme,arithmetic-expressions,Recursion,Scheme,Arithmetic Expressions,我是scheme的初学者,我正在尝试学习一些算术递归。我似乎无法用计划来完成这项工作并产生正确的结果。例如,我试图通过对字符串中的每个字符进行算术运算来为字符串生成一个整数键。在本例中,字符串是一个列表,例如:'(h e l o)。我需要执行的算术是: 对于字符串中的每个字符do-->(33*常量+字母表中字母的位置) 其中常量为输入,字符串作为列表输入 到目前为止,我有: (define alphaTest (lambda (x) (cond ((eq? x 'a) 1)
(define alphaTest
(lambda (x)
(cond ((eq? x 'a) 1)
((eq? x 'b) 2))))
(define test
(lambda (string constant)
(if (null? string) 1
(* (+ (* 33 constant) (alphaTest (car string))) (test (cdr string)))
我试图测试一个简单的字符串(test’(ab)2),但我无法产生正确的结果。我意识到我的递归一定是错的,但我已经玩了好几个小时了,每次都碰壁。有人能为实现这种算术递归提供帮助吗?谢谢你。请记住,我是Scheme语言的业余爱好者:)
编辑
我希望通过使新常量=(+(*33常量)(alphaTest(car字符串)),在字符串的每次迭代中更改输入的常量。我期望输入字符串’(ab)和常量2的输出应如下所示:
第一次迭代(a):(+(*332)(1))=67和=67,常数变为67第二次迭代(b):(+(*3367)(2))=2213和=2213,常数变为2213
(test '(a b) 2) => 2280
这就是你要找的吗
(define position-in-alphabet
(let ([A (- (char->integer #\A) 1)])
(λ (ch)
(- (char->integer (char-upcase ch)) A))))
(define make-key
(λ (s constant)
(let loop ([s s] [constant constant] [sum 0])
(cond
[(null? s)
sum]
[else
(let ([delta (+ (* 33 constant) (position-in-alphabet (car s)))])
(loop (cdr s) delta (+ sum delta)))]))))
(make-key (string->list ) 2) => 0
(make-key (string->list ab) 2) => 2280
顺便问一下,该过程是否应该用于包含字母以外的字符(如数字或空格)的字符串?在这种情况下,在字母表中的位置可能会产生一些令人惊讶的结果。要制作一个合适的键,您可以只调用char->integer
,而不必费心于字母表中的位置char->integer
将为每个字符提供不同的数字,而不仅仅是字母表中的每个字母。这里有一个解决方案(在MIT Gnu方案中):
(define position-in-alphabet
(let ([A (- (char->integer #\A) 1)])
(lambda (ch)
(- (char->integer (char-upcase ch)) A))))
(define (test chars constant)
(define (loop chars result)
(if (null? chars)
result
(let ((r (+ (* 33 result) (position-in-alphabet (car chars)))))
(loop (rest chars) (+ r result)))))
(loop chars constant))
(test (list #\a #\b) 2)
样本输出:
(test '(a) 2)
;Value: 67
(test '(a b) 2)
;Value: 2213
我只是在每次递归调用中转换常量,并在字符串用完时将其作为值返回
我去掉了lambda表达式,以便更容易看到发生了什么。(此外,在这种情况下,实际上并不需要lambda表单。)
您的测试程序定义似乎已被破坏:
(define test
(lambda (string constant)
(if (null? string)
1
(* (+ (* 33 constant)
(alphaTest (car string)))
(test (cdr string)))
您的代码如下所示:
- 创建一个接受两个参数的过程
test
<代码>字符串
和常量
如果string
为空,则传递值1以结束递归。否则,乘以以下值:
- 某个项x=(33*常数)+(字母测试(汽车字符串)),和
- 某个术语y是递归传递(cdr字符串)到测试过程的输出
我不知道术语y将如何计算,因为“test”需要两个参数。我的翻译出了一个错误。此外,括号是不平衡的。计算中有一些奇怪的地方,我无法指出——试着做一次纸上评估,看看在每次递归调用中可能会计算出什么。感谢您的及时回复Ben!回答你的问题,不,我没有考虑字符串中的特殊字符,只有字母。您的代码可以工作,但是我忘了提到我需要通过将常量设置为每次迭代的总和来不断更新常量。我尝试向循环(x常量)添加另一个参数,然后在调用循环时,添加(*1 sum)作为x传递,但这样做时,sum为0。我该怎么做才能把求和的结果作为新常数传递呢?现在我想我明白了。在这种情况下,您可以使用当前常量计算和,并且只需在第一次迭代之外的所有迭代中将新和作为新常量传递。我已经编辑了解决方案来说明。或者,如果常量应该是零长度字符串的键,那么Ankur的解决方案是正确的。感谢更新您的解决方案。你给我的帮助很大,我非常感激。我几乎完全明白了这一点,但我更新常数的意思是,我不希望常数是:新常数+和,而只是新常数,而不将自身添加到和。我会用预期的结果更新我原来的问题来说明这一点。非常感谢你,本,你帮我省去了一个大麻烦。已解决。您描述了如何处理字符串的每个字符,但没有描述如何组合每个字符的结果以提供最终的单个数字。另外,如果您描述了(test'(#\a#\b)2)的预期结果,也会有所帮助。
我更新了问题。谢谢,我是戈佐纳。
(define test
(lambda (string constant)
(if (null? string)
1
(* (+ (* 33 constant)
(alphaTest (car string)))
(test (cdr string)))