递归功率函数:方法

时间:2014-03-13 19:39:30

标签: c recursion pow

我正在编程一段时间(初学者),递归函数对我来说是一个有点抽象的概念。我不会说我卡住了,程序运行正常,我只是想知道函数本身是否可以在代码中没有pow函数的情况下编写(但仍然完全按照问题所示)

问题: http://prntscr.com/30hxg9

我的解决方案:

#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); 但是执行失败了,我还在回溯原因。

9 个答案:

答案 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);
}

这减少了所需的递归次数,使代码更节省时间和空间。希望这会有所帮助!