算术递归

时间:2013-04-10 03:54:18

标签: recursion scheme arithmetic-expressions

我是计划的初学者,我正在尝试学习一些算术递归。我似乎无法用这个方案来解决这个问题并产生正确的结果。对于我的例子,我试图通过对字符串中的每个字符进行算术来为字符串生成一个整数键。在这种情况下,字符串是一个列表,例如:'(h e l l o)。我需要执行的算法是:

对于字符串中的每个字符,请执行以下操作:> (33 *常数+字母表中的字母位置) 其中常量是输入,字符串作为列表输入。

到目前为止,我有这个:

(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)))

我正在尝试测试一个简单的字符串(测试'(a b)2),但我无法产生正确的结果。我意识到我的递归肯定是错的,但我每次都在玩弄它几个小时,然后撞墙。任何人都可以为实现此算术递归提供任何帮助吗?谢谢,麻烦您了。请记住,我是Scheme语言的业余爱好者:)

修改 我希望通过使新的常量=(+(* 33常量)(alphaTest(car string)))来保持输入以改变字符串的每次迭代。我期望输入字符串'(a b)和常数2的输出应该如下:

第一次迭代'(a):( +(* 33 2)(1))= 67 sum = 67,常数变为67
第二次迭代'(b):( +(* 33 67)(2))= 2213 sum = 2213,常数变为2213

(test '(a b) 2) => 2280

3 个答案:

答案 0 :(得分:1)

这是你正在寻找的吗?

(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
BTW,是否应该对包含除字母数字或空格以外的字符的字符串起作用?在这种情况下,position-in-alphabet可能会产生一些令人惊讶的结果。要制作一个合适的密钥,您可以致电char->integer而不必费心position-in-alphabetchar->integer会为每个字符提供不同的数字,而不仅仅是字母表中的每个字母。

答案 1 :(得分:1)

(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)

答案 2 :(得分:0)

这是一个解决方案(在MIT-Gnu计划中):

(define (alphaTest x)
  (cond ((eq? x 'a) 1)
    ((eq? x 'b) 2)))

(define (test string constant)
  (if (null? string) 
      constant
      (test (cdr string) 
        (+ (* 33 constant) (alphaTest (car string))))))

示例输出:

(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; stringconstant

  • 如果string为null,则传递值1,以结束递归。否则,乘以以下值:

    • 某个词x是=(33 *常数)+(alphaTest(car string)),
    • 某个术语y是递归传递(cdr字符串)到测试过程的输出

我不知道y将如何评估,因为'test'需要两个参数。我的口译员犯了一个错误。而且,括号是不平衡的。并且有一些奇怪的计算,我无法指责 - 尝试进行纸质评估,看看在每次递归调用中可能会计算出什么。