使用递归乘以幂

时间:2010-12-03 06:59:43

标签: c loops recursion

我正在寻找一种编程程序的方法,该程序只使用递归循环将整数乘以指数。我对递归的理解非常有限,但是能够编写一些东西来给出一个阶乘:

int fac2(int n)
{
    if (n == 1){
        return 1;
    } else {
        return n*fac2(n-1);
    }
}

我有办法找到电源,但它使用for循环:

int my_power(int x, int e)
{
    int i, total;
    total = 1;
    for (i = 1; i <= e; i++){
    total *= x;
    }
    return total;
}

如何使用递归替换此for循环?

7 个答案:

答案 0 :(得分:5)

int my_power (int x, int e) {
  if (e == 0) return 1;

  return x * my_power(x, e-1);
}

答案 1 :(得分:2)

请记住,递归函数会调用自身,直到达到某种基本情况为止。你的基本案例是什么?将一个数字提升到一个能力是喜欢说你要增加一些数字x次。提示是调用递归函数,将函数减少一,直到达到所需的基本情况。

答案 2 :(得分:2)

使用戴夫安德森作为基础,但也考虑其中的特殊情况:

1) x is 0 
2) e is negative.

同样,没有代码,所以你可以尝试自己解决: - )

更新:确保创建了大量测试用例,并确保每个人都按照您的想法运行。一旦测试通过,您就会知道您的递归电源功能正常工作。

示例:我有时间自己解决这个问题,但我会通过测试提出解决方案:

int main(void)
{
    // n = 0 special case
    test(0, 0, 1);
    test(4, 0, 1);
    test(-5, 0, 1);

    // x = 0 special case
    test(0, 0, 1);
    test(0, 2, 0);

    // normal use
    test(4, 1, 4);
    test(4, -1, 0.25);
    test(-4, 3, -64);
    test(8, 2, 64);
    test(2, 3, 8);
    test(2, -3, 0.125);
    test(2, -5, 0.03125);

    // Invalid input tests
    std::cout << std::endl << "Invalid input tests" << std::endl;
    test (0, -2, NULL);
    test(0, -4, NULL);


    // Negative Tests
    std::cout << std::endl << "Negative tests (expect failure)" << std::endl;
    test(4, 0, 4);
    test(2, 1, 1);
    test(2, -5, 0.0313);

    return 0;
}

double power(int x, int n)
{
    // check for invalid input
    if (n == 0)
    {
        return 1;
    }

    if (n > 0)
    {
        return x * power(x, n - 1);
    }
    else if (n < 0)
    {
        return 1 / (x * power(x, -n - 1));
    }
}

bool test(int x, int n, double expected)
{
    if (x == 0 && n < 0)
    {
        std::cout << "Testing " << x << "^" << n << ", result = 'Invalid input'." <<  std::endl;
        return false;
    }

    double result = power(x, n);
    std::cout << "Testing " << x << "^" << n << ", result = " << result << ". Expected " << expected << " - test " << ((result == expected) ? "PASSED" : "FAILED") <<  std::endl;
    return true;
}

<强>输出:

Testing 0^0, result = 1. Expected 1 - test PASSED
Testing 4^0, result = 1. Expected 1 - test PASSED
Testing -5^0, result = 1. Expected 1 - test PASSED
Testing 0^0, result = 1. Expected 1 - test PASSED
Testing 0^2, result = 0. Expected 0 - test PASSED
Testing 4^1, result = 4. Expected 4 - test PASSED
Testing 4^-1, result = 0.25. Expected 0.25 - test PASSED
Testing -4^3, result = -64. Expected -64 - test PASSED
Testing 8^2, result = 64. Expected 64 - test PASSED
Testing 2^3, result = 8. Expected 8 - test PASSED
Testing 2^-3, result = 0.125. Expected 0.125 - test PASSED
Testing 2^-5, result = 0.03125. Expected 0.03125 - test PASSED

Invalid input tests
Testing 0^-2, result = 'Invalid input'.
Testing 0^-4, result = 'Invalid input'.

Negative tests (expect failure)
Testing 4^0, result = 1. Expected 4 - test FAILED
Testing 2^1, result = 2. Expected 1 - test FAILED
Testing 2^-5, result = 0.03125. Expected 0.0313 - test FAILED

答案 3 :(得分:1)

正确的做法是通过注意:

  • x n =(x n / 2 2 ,如果n是偶数
  • x n = x *(x ⊦n/2⫞ 2 ,如果n为奇数
  • x 1 = x
  • x 0 = 1

其中“⊦n/2⫞”表示n / 2的整数部分(当n是整数变量时,n是n在C中给出的)。

与读数

的阶乘形成对比
  • N! = n *(n - 1)!,如果n> 0
  • 0! = 1

你应该能够以自我为基础编写一个递归的求幂程序。

答案 4 :(得分:0)

这是给你的伪代码:

FUNCTION mypower(number, exponent)
    IF exponent == 0 THEN:
        RETURN 1
    ELSE IF exponent > 0 THEN:
        RETURN number * mypower(number, exponent - 1)
    ELSE:
        RETURN 1 / mypower(number, -(exponent))

哦,返回值应为double

这是实际的代码:

double mypower(int n, int e) {
    if (e == 0)
        return 1;
    else if (e > 0)
        return n * mypower(n, e - 1);
    else
        return 1 / mypower(n, -e);
}

答案 5 :(得分:0)

据我所知,对于任何可能的情况(某人将“asdfj”设置为x或e不太可能),此函数将起作用。

#include <stdio.h>

double my_power(int x, int e)
{
    if (x == 0)
    {
        return 0;
    }
    if (e == 0)
    {
        return 1;
    }
    if (e > 0)
    {
        return x * my_power(x, e-1);
    }
    if (e < 0)
    {
        return 1/(x*my_power(x, -e-1));
    }
}

答案 6 :(得分:0)

有一种思考方式需要我们走出C-land,但它的内心和功能非常简单,值得考虑。

递归和迭代并不像它们最初看起来那么不同。在certain level,实际上很难区分它们。我们不会去那里,但考虑一下for循环的递归实现(没有特定的语言):

for (i, n, f, a) = 
  if (i > n) {
    return a
  } else {
    return for (i+1, n, f, f(a, i))
  }

(顺便说一下,a被称为“累加器”,因为它累积了每个“循环”的值。

对您来说可能是新鲜事的一件事是,上述处理函数与任何其他数据类型一样,称为“first-class functions”。这通常不是你在C中做的事情(你可以通过传递函数指针以有限的方式完成它),但它是一个非常强大的概念,值得学习。

使用for的上述定义,我们将您的阶乘函数编写为:

mult(a,b) = a*b
fac(n) = for (1, n, mult, 1)

这会推动每个i乘以累加器。

另一个强大的概念(遗憾的是,C根本不支持)是匿名函数,它们只是在没有名称的情况下创建的函数。我将对匿名函数使用语法e -> ...,其中...是一个表达式(例如x -> x+1),(a,b)表示一对变量。在C语言中,匿名函数可能看起来没用,但是如果你可以像传递数字那样轻松传递函数,那么可以将fac简化为一行:

fac(n) = for (1, n, (a,i) -> a*i, 1)

pow可以写成:

pow(x, e) = for(1, e, (a,i) -> a*x, 1) 

展开for,你就得到了pow的递归定义。

虽然这给你一个递归函数,但还有另一个实现(实际上是Alexandre的),它的效率更高。