wpcockroach

导航

Exponentiation 的 O(logn) 算法

求幂的O(logn)算法应该已经众所周知了。这里就不做深入地分析,只是简单介绍下并提供两个样板程序。在写下O(logn)算法之前,还是先补充介绍下算法的数学背景。

Exponentiation

显然,上面的数学式具有递归形式。所以,递归实现可以写成:

另外,我们也可以把递归式转化为非递归的循环实现方式。先用一个例子来阐述下循环的特点。我用a^15为例。

  1. 令 res = a^15,base = a,exponent = 15。因为exponent是奇数,所以 res = a^14 * a。
  2. 令 res1 = a^14,则 base = a,exponent = 14,res = res1 * a。
  3. 分析 res1,因为exponent为偶数,所以 res1 = (a^2)^7。
  4. 令 b = a^2,则 res1 = b^7,base = b,exponent = 7。重复步骤1。因为exponent是奇数,所以 res1 = b^6 * b。
  5. 重复步骤2。令res2 = b^6。则 base = b,exponent = 6,res1 = res2 * b。
  6. 重复步骤3。res2 = (b^2)^3。
  7. 重复步骤4。令c = b^2。则res2 = c^3,base = c, exponent = 3。因为exponent是奇数,所以res2 =  c^2 * c。
  8. 重复步骤2。令 res3 = c^2。则 res2 = res3 * c。
  9. 从以上的分析,我们看到 res = res1 * a = res2 * b * a = res3 * c * b * a。

可以发现,res3 * c * b * a中,每次乘法操作都发生在exponent为奇数时。而每次当exponent为偶数时,我们都是在计算b,c和res3,而且b,c和res3都是a的偶次幂。再结合最开头的数学式,我们可以得到如下的代码:

 

posted on 2009-03-14 16:44  wpcockroach  阅读(585)  评论(0编辑  收藏  举报