解释题,说简单也简单,难在如何表达清楚。
首先解释下代码的变化
(defn expmod[base exp m]
(cond (= exp 0) 1
(even? exp) (mod (square (expmod base (/ exp 2) m)) m)
:else (mod (* base (expmod base (- exp 1) m)) m)
)
)
(defn expmod[base exp m]
(cond (= exp 0) 1
;///这里变了
(even? exp) (mod (* (expmod base (/ exp 2) m) (expmod base (/ exp 2) m)) m)
:else (mod (* base (expmod base (- exp 1) m)) m)
)
)
之所以会从对数级变成线性级,主要原因在于代码的展开方式,在使用square方法的时候,先计算一遍expmod 函数内的值,然后对计算结果进行平方计算。在使用乘法的时候,是计算了两次expmod函数内的值,然后再将结果进行相乘计算,在偶数的情况下 每次都会将同一个运算多做一次。
假设我们要计算的exp为1024,那么使用square总共要计算expomd表达式10次,即以2为底1024的对数。使用乘号的话,需要2+4+8+++1024=2046 ,可以简略看做2*1024也就是线性级函数。