通过递归的球拍条件和系列之和

时间:2017-01-21 11:10:36

标签: scheme lisp racket

我是Racket的新手。我需要将所有小于1000的自然数(或任何第n个值)相加,并且数字可以被3或5整除。我有一个代码可以做到但是使用迭代。但我必须通过递归来做同样的事情。代码如下:

(define (sum-divisibles limit)
  (for/sum ([i (in-range 1 limit)]
            #:when (or (divides? i 3)
                       (divides? i 5)))
    i))

(define (divides? m n)
  (= 0 (remainder m n)))  

我需要做同样的事情,但是使用递归而不是循环或迭代。

3 个答案:

答案 0 :(得分:1)

EVAL "local old_prefix_len = string.len(ARGV[1]) local keys = redis.call('keys', ARGV[1] .. '*') for i = 1, #keys do local old_key = keys[i] local new_key = ARGV[2] .. string.sub(old_key, old_prefix_len + 1) redis.call('rename', old_key, new_key) end" 0 "datamine::production::" "datamine::development::" 为正数,n为前身m

现在,假设您知道m = n - 1等于某个值(sum-divisibles m)。您将如何计算s

尝试编写一个值为(sum-divisible n)且值为n的函数,并计算s的总和。

n

然后,您将能够根据 (define (recur n s) ...) 定义sum-divisibles以及limit sum-divisibles的递归应用。当limit - 1为零时,您还需要处理递归的基本情况。

答案 1 :(得分:1)

这很简单,只要您将循环中的每个迭代可视化为函数调用。考虑一下:原来的for循环从1开始,包括limit-1。这与从limit-1开始相同,在每个函数调用时将限制减少1,并在到达0时停止。

要记住编写递归过程有两件重要的事情:

  1. 我们必须确保在某个时刻停止 - 这称为基本情况;对于此示例,当我们到达0时会发生这种情况(因为原始循环包含1)。
  2. 我们必须结合我们在调用递归时获得的部分结果:如果当前数字恰好可以被35整除,那么我们添加它其余的递归调用,否则我们忽略它,但仍然继续推进递归,直到我们达到基本情况。
  3. 这就是我的意思:

    (define (sum-divisibles limit)
      (cond ((= limit 0) 0)                             ; base case, stop recursion
            ((or (divides? limit 3) (divides? limit 5)) ; does the condition hold?
             (+ limit                                   ; then we add current value
                (sum-divisibles (- limit 1))))          ; and advance the recursion
            (else                                       ; otherwise skip it
             (sum-divisibles (- limit 1)))))            ; and advance the recursion
    

    请注意初始limit值,请记住,在原始代码中,limit 不会添加到总和中(迭代会在到达之前停止),因此,调用递归版本的等效方法是:

    (sum-divisibles (- n 1))
    

    例如,要使用您的代码获得与(sum-divisibles 50)相同的值,我们必须在递归版本中将其称为:

    (sum-divisibles 49)
    => 543
    

    或者你可以编写一个帮助程序,在调用实际的递归过程之前,将一个输入limit减少一个,但是剩下的就是读者的练习。

答案 2 :(得分:1)

可以使用'named let'进行递归:

(define limit 1000)

(let loop ((n 1)                 ; starting values
           (sum 0))
  (cond
    [(> n limit) sum]            ; print out sum if limit reached;

    [(or (= 0 (modulo n 3))      ; if n is divisible by 3 or 5
         (= 0 (modulo n 5)))
     (loop (add1 n) (+ sum n))]  ; add this number to sum and loop again with next number

    [else                        ; if not divisible
     (loop (add1 n) sum)]        ; loop with next number without adding to sum
    ))