我正在编程一段时间(初学者),递归函数对我来说是一个有点抽象的概念。我不会说我卡住了,程序运行正常,我只是想知道函数本身是否可以在代码中没有pow函数的情况下编写(但仍然完全按照问题所示)
我的解决方案:
#include<stdio.h>
#include<math.h>
int power(int, int);
int main(void)
{
int x, n;
printf("Enter a number and power you wish to raise it to: ");
scanf_s("%d %d", &x, &n);
printf("Result: %d\n", power(n, x));
return 0;
}
int power(int x, int n)
{
if (n == 0) return 1;
if (n % 2 == 0) return pow(power(x, n / 2), 2);
else return x * power(x, n - 1);
}
我试过这样做:power(power(x,n - 1),2); 但是执行失败了,我还在回溯原因。
答案 0 :(得分:8)
重写函数时,在这种情况下不要忽视递归的主要好处,即减少所需的乘法运算次数。例如,如果n = 8,则将x * x计算为val1,然后将val1 * val1计算为val2,将最终答案计算为val2 * val2(3次乘法),而不是计算x * x * x * x * x * x * x * x(7次乘法)。
这种差异对于小整数来说是微不足道的,但是如果你将这个操作放在一个大循环中,或者你用非常大的数字表示或可能是巨大的矩阵替换整数,那么这很重要。
这是摆脱pow()函数而不去除递归效率的一种方法:
#include<stdio.h>
#include<math.h>
int power(int, int);
int main(void)
{
int x, n;
printf("Enter a number and power you wish to raise it to: ");
scanf_s("%d %d", &x, &n);
printf("Result: %d\n", power(x, n));
return 0;
}
int power(int x, int n)
{
int m;
if (n == 0) return 1;
if (n % 2 == 0) {
m = power(x, n / 2);
return m * m;
} else return x * power(x, n - 1);
}
答案 1 :(得分:2)
对于电源功能(让我们说,x到n次幂)你有两种情况:
exponent=0
exponent=n
对于第一种情况,您只需要返回1.在另一种情况下,您需要将x返回到n减去1的幂。在那里,你只是递归地使用了这个函数。
int power(int x, n)
{
if(n == 0) return 1;
else return x * power(x, n-1);
}
答案 2 :(得分:2)
代码:
int power(int x, int n)
{
if (n == 0) return 1;
if (n % 2 == 0) return power(power(x, n / 2), 2);
else return x * power(x, n - 1);
}
不起作用,因为当n是均匀功率时,n = 2是偶数,然后用n = 2调用功率,这是偶数,然后用n = 2来调用幂...直到...堆栈溢出!
简单的解决方案:
int power(int x, int n)
{
if (n == 0) return 1;
if (n % 2 == 0) {
if (n == 2) return x * x;
return power(power(x, n / 2), 2);
}
else return x * power(x, n - 1);
}
答案 3 :(得分:1)
double result = 1;
int count = 1;
public double power(double baseval, double exponent) {
if (count <= Math.Abs(exponent)){
count++;
result *= exponent<0 ?1/baseval:baseval;
power(baseval, exponent);
}
return result;
}
这适用于正值,负值和0值
答案 4 :(得分:0)
简单但有n次乘法。以上示例更有效,因为它们在一次迭代中对两个操作进行分组
int power(int x, int n)
{
if (n == 0) return 1;
return x * power(x, n-1);
}
答案 5 :(得分:0)
以下是 ruby 的解决方案,也适用于负指数
# for calculating power we just need to do base * base^(exponent-1) for ex:
# 3^4 = 3 * 3^3
# 3^3 = 3 * 3^2
# 3^2 = 3 * 3^1
# 3^1 = 3 * 3^0
# 3^0 = 1
# ---------------------------------------------------------------------------
# OPTIMIZATION WHEN EXPONENT IS EVEN
# 3^4 = 3^2 * 3^2
# 3^2 = 3^1 * 3^1
# 3^1 = 3^0
# 3^0 = 1
# ---------------------------------------------------------------------------
def power(base, exponent)
if(exponent.zero?)
return 1
end
if(exponent % 2 == 0)
result = power(base, exponent/2)
result = result * result
else
result = base * power(base, exponent.abs-1)
end
# for handling negative exponent
if exponent < 0
1.0/result
else
result
end
end
# test cases
puts power(3, 4)
puts power(2, 3)
puts power(0, 0)
puts power(-2, 3)
puts power(2, -3)
puts power(2, -1)
puts power(2, 0)
puts power(0, 2)
答案 6 :(得分:0)
我使用C ++的方法仅适用于非负数。
#include <iostream>
using namespace std;
long long power(long long x, long long y) {
if (y == 0) {
return 1;
}
else {
y--;
return x*power(x,y);
}
}
main() {
long long n, x;
cin >> n >> x;
cout << power(n,x);
}
答案 7 :(得分:0)
int pow(int a, int n) {
if(n == 0) return 1;
if(n == 1) return a;
int x = pow(a, n/2);
if(n%2 == 0) {
return x*x;
}
else {
return a*x*x;
}
}
答案 8 :(得分:0)
您要避免使用pow()
,对吗?因此,您改为使用power()
,导致在参数列表中进行递归调用。这导致了分段错误。
首先,让我们了解问题的原因。我对算法进行了笔和纸运算,结果非常有趣。事实证明,对于x和n的任何值,经过一定数量的递归后,总会得到power(1, 2)
。这也意味着经过一定次数的递归后,power(1, 2)
也会导致power (1, 2)
。因此,power()
中的power()
导致无限递归,从而导致堆栈溢出。
现在,您的问题。是的,无需使用pow()即可完成此操作,因为pow(a,2)可以简单地写为a * a。因此,这是对您的代码的轻微修改:
int power(int x, int n)
{
if (n == 0) return 1;
if (n % 2 == 0) return power(x, n / 2) * power(x, n / 2);
else return x * power(x, n - 1);
}
但是,为什么要这样呢?一种更有效的方法如下。
int power(int x, int n)
{
if (n == 0) return 1;
if (n % 2 == 0) return power(x * x, n / 2);
else return x * power(x * x, n / 2);
}
这减少了所需的递归次数,使代码更节省时间和空间。希望这会有所帮助!