Algorithm 什么';我的迭代expmod实现有什么问题?
以下程序用于计算Algorithm 什么';我的迭代expmod实现有什么问题?,algorithm,iteration,lisp,primes,sicp,Algorithm,Iteration,Lisp,Primes,Sicp,以下程序用于计算base^expo mod m (define (expmod base expo m) (define (square n) (* n n)) (define (even? n) (= (remainder n 2) 0)) (define (expmod-iter base expo m result) (cond ((= expo 0) result) ((even? expo) (expmod-
base^expo mod m
(define (expmod base expo m)
(define (square n)
(* n n))
(define (even? n)
(= (remainder n 2) 0))
(define (expmod-iter base expo m result)
(cond ((= expo 0) result)
((even? expo)
(expmod-iter base
(/ expo 2)
m
(remainder (square result) m)))
(else
(expmod-iter base
(- expo 1)
m
(remainder (* base result) m)))))
(expmod-iter base expo m 1))
事实上,我正试图转换为它的迭代等价物。以下是原始程序:
(define (expmod base exp m)
(cond ((= exp 0) 1)
((even? exp)
(remainder (square (expmod base (/ exp 2) m))
m))
(else
(remainder (* base (expmod base (- exp 1) m))
m))))
(expmod 42 1000000007 1000000007)
的结果是270001056,但根据,由于1000000007是素数,因此结果应该是42
我做错了什么?这是我对迭代
expmod
的实现:
(define (expmod base exp mod)
(let loop ((base base)
(exp exp)
(result 1))
(cond ((zero? exp) result)
((odd? exp) (loop base (sub1 exp) (modulo (* result base) mod)))
(else (loop (modulo (sqr base) mod) (quotient exp 2) result)))))
在球拍测试与您的样本输入。如果不使用Racket,则需要使用合适的实现替换sub1
和sqr
请注意,虽然您必须为偶数指数平方基数,但实际上您可以修改其结果,正如您在我的代码中所看到的。所以它不会变得太大。在偶数情况下,你的
基数需要平方。另外,顺便说一句,Scheme提供了一个内置的even?
谓词,您不需要定义自己的谓词。@ChrisJester Young在我平方base
之后,在偶数情况下,即使在最简单的情况下,事情似乎也会出错。例如,(expmod 3 5 8)
将计算为1
,而3^5=243=30*8+3
原始递归函数不是尾部递归函数。@tfb尾部递归过程和迭代过程之间的区别是什么?我认为,在的术语中,中的tailrecsum
函数是迭代的,而不是(尾部)递归的。澄清:相对于原始的非尾部递归版本,值的累积是“反向的”;您有expmod 2 4->expmod iter 2 4 1->expmod iter 2 2 2(正方形1)->expmod iter 2 1(正方形1)
。。。