在power算法中求一个数x的n次方分成两部分,一是当n为偶数时计算方法,另一部分是当n为奇数时的计算方法。在n的"分解"过程中,还可能还会出现偶数和奇数部分的代码都参与计算。
 
n为偶数,计算方式:
   假设 Y = x*x , Z = n / 2;
   那么xn = YZ。例如如下步骤:
      28 = 44。 (1)
      44 = 162。  (2)
      162 = 2561。(3) // 此时n == 1,即结果最终转换成了一个数的奇次方。
 
   while ((n & 1) == 0) {  // 当一个数的第0位为0,表示此数是偶数。
      n >>= 1;    // 等价于指数n除2
      x = op(x, x);
   }
 
n为奇数,计算方式:
   公式:xn = xn-1 * x。既然n此时为奇数,那么n-1就为偶数了。例如如下步骤:
   27 =26 * 2。                             (1)
   26 * 2 = 43* 2。                          (2)
   43* 2 = (42 * 4) * 2 =  42 * (4 * 2) = 42 * 8。  (3)
   42 * 8 = 161 * 8。                         (4)
 
  T result = x; // 步骤(1)被隐含执行了
   n >>= 1;
   while (n != 0) {
     x = op(x, x);
     if ((n & 1) != 0) // 第0位为1是奇数。n为奇数,则执行特定操作,如上面的步骤(3)
       result = op(result, x);
     n >>= 1;
   }
 
n为较特殊的偶数情况:
   如当x为2,n为14时。执行偶数如下
   214 = 47
执行上面操作后,变为x是4,n是7的计算方式,也就是我们可以认为值的计算已被转换成了n为奇数情形的计算方式了。
   最后注意对stl中的这算法不必局限于纯数学运算--注意泛型中所提到的connect。
 
  1. template <class T, class Integer, class MonoidOperation> 
  2. T power(T x, Integer n, MonoidOperation op) {                                     
  3.     if(n == 0)       
  4.         return x;                                                                 
  5.     else {       
  6.         while((n & 1) == 0) {   
  7.             x = op(x, x);
  8.             n >>= 1;
  9.         }                                                 
  10.         T result = x;     
  11.         n >>= 1;     
  12.         while(n != 0) {    
  13.             x = op(x, x);                                                         
  14.             if((n & 1) != 0)                                                      
  15.                 result = op(result, x);    
  16.             n >>= 1;
  17.         return result;  
  18.     }