版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013810296/article/details/67639741
编写程序计算整数X的N次方,这个问题一个难点在于如何减少运算复杂度
遍历自乘法
//输出X的N次方,连续自乘
//O(N)
long int Power(int X, unsigned int N)
{
unsigned long temp = 1;
for (int i = 0; i < N; i++)
temp = temp * X;
return temp;
}
这个算法依次进行N次对X的乘法,运算复杂度为O(N),这是最直接简单的方法,但这个算法是可以提高的,如日常中计算64,我们下意识都会用8*8而不是将两个8分别各计算出来再相乘
因此简单的遍历相乘这个算法中隐含了重复性的计算
对分法
//若M为偶数输出true,为奇数输出false
bool IsEven(unsigned int M)
{
//return (M % 2 == 0 ) ? true : false;
return ((M & 0x01) == 0) ? true : false;
}
//递归计算X的N次方
//O(logN)
long int Pow_rec( int X, unsigned int N)
{
if (N == 0)
return 1;
if (IsEven(N))
return Pow_rec(X*X, N / 2);
else
return Pow_rec(X*X, N / 2)*X;
}
这个算法中使用递归方法,每次递归中判断指数N的奇偶性,如果为偶数则计算
T | N | return |
---|---|---|
1 | 33 |
|
2 | 16 |
|
3 | 8 |
|
4 | 4 |
|
5 | 2 |
|
6 | 1 |
|
容易得到一共进行了6次递归,递归次数等于
上述程序中要求底数X为整数,指数N为正整数,只覆盖了幂运算的一小部分,实际中需要考虑的情况有:
- 指数N为负整数
//递归计算X的N次方,考虑N为负整数
//O(logN)
double Powe_rec_neg(int X, int N)
{
if (N < 0 && X == 0)
return 0;
if (N < 0)
return -(1.0 / (double)Pow_rec(X, (unsigned int)-N));
return Pow_rec(X, N);
}
- 底数X为浮点型实数
修改类型即可,但需要注意在判断底数X==0
和指数N<0
同时满足的情况时,由于此时X为浮点型,因此不能直接使用==
,而应该单独判断:
bool equal(double elem1, double elem2)
{
if ((elem1 - elem2 < 0.0000001) && (elem1 - elem2 > -0.0000001))
return true; //相等
else
return false; //不相等
}
- 指数N为小数
指数为小数或者分数时,实际上是开方运算,与简单的幂运算已经完全不同了,这部分需要另外单独进行讨论
同时受限于long int长度,算法中只能计算小于
232 次方的幂,如何对于大数进行幂运算则是另外一个并不简单的问题