简体   繁体   English

C中数据结构的幂运算和算法分析

[英]exponentiation in Data Structures and Algorithm Analysis in C

When addressed exponentiation in chapter 2, the author mentioned 在第2章谈到幂运算时,作者提到

"The number of multiplications required is clearly at most 2 log n(the base is 2), because at most two multiplications (if n is odd) are required to halve the problem. Again,a recurrence formula can be written and solved." “显然,所需的乘法数最多为2 log n(底数为2),因为最多需要两次乘法(如果n为奇数)就可以使问题减半。同样,可以编写并求解递推公式。”

The code as follow: 代码如下:

int pow( int x, unsigned int n)
{
/*1*/ if( n == 0 )
/*2*/ return 1;
/*1*/ if( n == 1 )
/*4*/ return x;
/*5*/ if( even( n ) )
/*6*/ return( pow( x*x, n/2 ) );
else
/*7*/ return( pow( x*x, n/2 ) * x );
}

Q : As the author said, :正如作者所说,

2^16 need at most 8 multiplications 2 ^ 16最多需要8个乘法

2^15 ... 7 ... 2 ^ 15 ... 7 ...

2^14 ... 7 ... 2 ^ 14 ... 7 ...

2^13 ... 7 ... 2 ^ 13 ... 7 ...

2^12 ... 7 ... 2 ^ 12 ... 7 ...

In fact, I perfrom the code: 实际上,我执行以下代码:

2^16 .... 4 ... 2 ^ 16 .... 4 ...

2^15 .... 6 ... 2 ^ 15 .... 6 ...

2^14 ... 5 ... 2 ^ 14 ... 5 ...

2^13 ... 5 ... 2 ^ 13 ... 5 ...

2^12 ... 4 ... 2 ^ 12 ... 4 ...

So, is somewhere wrong? 那么,哪里出问题了?

Finding x^n will take at most 2 log n multiplications, since it is possible for n/2 to be odd at every iteration. 找到x ^ n 最多需要 2个log n乘法,因为n / 2在每次迭代中都可能是奇数。 For example: 例如:

pow(2, 15) --> pow(2 * 2, 7) * 2
           --> pow(4 * 4, 3) * 4 * 2
           --> pow(16 * 16, 1) * 16 * 4 * 2

This is six multiplications (two multiplications per function call); 这是六个乘法(每个函数调用两个乘法)。 2 * log(15) ~= 7.8 . 2 * log(15)〜= 7.8 So the upper bound is satisfied. 因此满足了上限。 The best case is n a power of 2, which takes only log n multiplications. 最好的情况是n的2的幂,仅需对数n乘法。

To calculate the complexity, consider that this algorithm reduces n by half k times, until n is between 1 and 2; 为了计算复杂度,请考虑该算法将n减少一半k倍,直到n在1和2之间; that is, we have: 也就是说,我们有:

1 ≤ n2 k < 2 1≤N / 2 k <2

So: 所以:

2 k ≤ n < 2 k+1 2 k≤Ñ<2 K + 1
⇒ k ≤ log n < k+1 ⇒k≤log n <k + 1
⇒ (log n) - 1 < k ≤ log n ⇒(log n)-1 <k≤log n

Thus, the algorithm takes log n steps, and since the worst case is two multiplications per step, at most 2 log n multiplications are required. 因此,该算法采取log n步,并且由于最坏的情况是每步两次乘法,因此最多需要2 log n乘法。

There's no contradiction or mistake -- the book gives an upper bound, and you're looking at the exact number of multiplications. 没有矛盾或错误-这本书给出了一个上限,您正在查看乘法的确切数量。

The exact number of multiplications (for n>0) is floor(log_2(n)) + bitcount(n) - 1. That's just by inspecting the code -- the even cases (which perform one multiplication) correspond to 0 bits in the input, the odd cases (which perform an extra multiplication) correspond to 1 bits in the input, and the code stops when it reaches the highest bit. 精确的乘法次数(对于n> 0)是floor(log_2(n))+ bitcount(n)-1。这只是通过检查代码-偶数情况(执行一次乘法)对应于0中的0位。输入时,奇数情况(执行额外的乘法运算)对应于输入中的1位,并且代码到达最高位时停止。

The book says that 2*log_2(n) is an upper bound for the number of multiplications. 这本书说2 * log_2(n)是乘法次数的上限。 That's consistent with the exact formula: floor(log_2(n)) <= log_2(n) and bitcount(n) - 1 <= log_2(n). 这与确切的公式一致:floor(log_2(n))<= log_2(n)和bitcount(n)-1 <= log_2(n)。 So floor(log_2(n)) + bitcount(n) - 1 <= 2*log_2(n). 所以floor(log_2(n))+ bitcount(n)-1 <= 2 * log_2(n)。

From the exact formula, you can see that the lower the bitcount of n, the worse the upper bound is. 从精确的公式中,您可以看到n的位数越低,上限越差。 The very worst cases are when n is a power of 2: then exactly log_2(n) multiplications will be performed, and the upper bound is off by a factor of 2. The very best cases are when n is one less than a power of 2: then the upper bound will be off by only 1. That matches your empirical table of results. 最坏的情况是n为2的幂,那么将精确执行log_2(n)乘法,并且上限以2为因数。最好的情况是n小于2的幂。 2:则上限仅偏离1。这与您的经验结果表相符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM