我无法在OCaml中找到更快版本的典型指数函数。以下是我要遵循的一些指导原则:
expt b n ==> b * (b * (b ...)
的典型递归指数版本,这个函数接收两个参数b和n,基本上是分而治之的。fastexpt b n => (b ^ (n / 2))^2
如果n是奇数,那么fastexpt b n => b * (b ^ (n - 1))
这是我到目前为止编写的代码:
let fastexpt : int -> int -> int
= fun b n ->
if n = 0 then 1
else if ((n mod 2) = 0) then (expt b (n / 2)) * (expt b (n / 2))
else b * (expt b (n - 1));;
我的问题是:有没有办法在不使用expt
函数的情况下编写此函数?
答案 0 :(得分:1)
你在这里做的是第一次使用分而治之的方法,然后使用正常的方法进行剩余的计算(如果我们认为你已经宣布expt
)
另一件事是,如果n
是奇数,你可以返回b * b^((n-1)/2) * b^((n-1)/2)
,这就是快速取幂的目的。
你应该做的只是将fastexpt
定义为递归并一直使用它:
let rec fastexpt : int -> int -> int
= fun b n ->
if n = 0 then 1
else
let b2 = fastexpt b (n / 2) in
if n mod 2 = 0 then b2 * b2
else b * b2 * b2;;