我是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)))
我需要做同样的事情,但是使用递归而不是循环或迭代。
答案 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
时停止。
要记住编写递归过程有两件重要的事情:
0
时会发生这种情况(因为原始循环包含1
)。3
或5
整除,那么我们添加它其余的递归调用,否则我们忽略它,但仍然继续推进递归,直到我们达到基本情况。这就是我的意思:
(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
))