我是一个初学者,试图理解这个无辜的C函数: 给定两个数字x和y,此函数计算x提升到y的幂。
/* Function to calculate x raised to the power y */
int power(int x, unsigned int y)
{
if( y == 0)
return 1;
else if (y%2 == 0)
return power(x, y/2)*power(x, y/2); //what's happening here?
else
return x*power(x, y/2)*power(x, y/2);
}
我正在努力追踪它们将两个函数的返回值相乘的部分。假设我将4和3作为x和y传递,我的函数跳转到第二个其他部分。然后我返回4*(power(4,1)*power(4,1))
据我所知,下一个调用是4*power(4,0)*power(4*0)
,因为y == 0返回1,它应该是4 * 1 * 1,我想要4 * 4 * 4。我在这里遗漏了一些东西。这个算法到底在做什么?
这个函数背后的逻辑是乘以x,y倍。任何人都可以告诉我这个简单的除法运算(或分而治之)如何实现逻辑?提前谢谢。
答案 0 :(得分:8)
使用的算法是exponentiation by squaring。它分为两部分,正整数n
因此,上述函数,对于偶数指数将返回
power(x, y/2)*power(x, y/2);
并且奇数指数将返回
x*power(x, y/2)*power(x, y/2);
它会按log(n)
时间计算功率。
对于2 5 ,它将被执行为:
5
是奇数,因此return 2*power(2, 5/2)*power(2, 5/2)
将被执行。 5/2 = 2
,因此return power(2, 2/2)*power(2, 2/2)
将被执行。 2/2 = 1
是奇数,因此return 2*power(2, 1/2)*power(2, 1/2)
将被执行。 1/2 = 0
,因此将返回power(2, 1/2)
,1
的基本条件。 所以,
return 2*power(2, 1/2)*power(2, 1/2)
会将2*1*1 = 2
返回给其来电者。 return power(2, 2/2)*power(2, 2/2)
会将2*2 = 4
返回给其来电者。 return 2*power(2, 5/2)*power(2, 5/2)
会将2*4*4 = 32
返回给其来电者。 更有效的版本是
int power(int x, unsigned int y)
{
if( y == 0)
return 1;
int t = power(x, y/2); // power is called only once instead of twice.
return y%2 ? x*t*t : t*t;
}
答案 1 :(得分:0)
为简单起见,以下功能以更容易理解的方式演示了递归:
int power(int x, unsigned int y)
{
if( y == 0)
return 1;
return x * power(x, y-1);
}
这显示了使用递归来处理幂计算的简单方法。你所拥有的方法仍然会大致做到这一点,但它的最大堆栈深度会更好(它会减少更多),因为它可以更好地划分工作。
不知道为什么你会在现实世界中使用它们。迭代可能会更加优越,或者可能是对数 - 乘法指数 - 反对数方法(也可以处理法定指数)。
另外,这种类型的计算也很容易出现溢出整数值,非常快,所以请注意。