《STL源码剖析》学习--6章--power算法分析

来源:互联网 发布:bootp端口号 编辑:程序博客网 时间:2024/05/16 19:36

最近在看侯捷的《STL源码剖析》,其中有许多不太明白之处,后经分析或查找资料有了些理解,现记录一下。

6章--power算法分析

书本中的算法如下所示:

template <class _Tp, class _Integer, class _MonoidOperation>_Tp __power(_Tp __x, _Integer __n, _MonoidOperation __opr){  if (__n == 0)    return identity_element(__opr);  else {    while ((__n & 1) == 0) {      __n >>= 1;      __x = __opr(__x, __x);    }    _Tp __result = __x;    __n >>= 1;    while (__n != 0) {      __x = __opr(__x, __x);      if ((__n & 1) != 0)        __result = __opr(__result, __x);      __n >>= 1;    }    return __result;  }}template <class _Tp, class _Integer>inline _Tp __power(_Tp __x, _Integer __n){  return __power(__x, __n, multiplies<_Tp>());}


此处的幂运算X^N,采用的思路是将十进制N化解为二进制,N=(2^0)*N0+(2^1)*N1+……,其中Ni为化为二进制时第i位(0或1)。

如:N=40,化为二进制时为101000,此时X^40 =X^[ (2^0)*0 +(2^1)*0+(2^2)*0+(2^3)*1+(2^4)*0+(2^5)*1]

可以化简为X^[(2^3)*1+(2^5)*1 ] = [X^(2^3)]*[X^(2^5)] ,X^[(2^i)*Ni] 后一项X^ {[2^ (i+1)] * Ni+1 },若Ni+1与Ni都为1,则前式后一项为前一项自己的平方。

幂运算用乘法来做,用移位运算和乘法运算来实现。

程序的思路:

(1)特殊情况,若N==0,则返回自己,与数学中X^0=1不相同。

(2)非特殊情况,

首先找到N化为2进制时最低位为1的那位,代码如第一个while循环,每次检测最低位是否为1,再进行右移判断,

 如N化为二进制为101000,退出while时,N=101,x = X^(2^3),从此处可以看出x相同于数制的位权。(程序中的中间值x这里我用小x表示,初值用X表示);

 然后对N去掉后面零的值逐位判断,每次都增大x,得到位权,如果为1,则与result相乘,直到N==0。


我们都知道,stl中的算法几乎总是最高效的,思考一下为什么不用N个数相乘呢?如果用N个数相乘O(N),而用此二分法则是O(logN),且从前面非0的位开始,提高了效率。

同时感觉进制转换算法与此类似。



0 0
原创粉丝点击