使用递归乘以幂

发布于 2024-10-06 04:16:37 字数 430 浏览 4 评论 0原文

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

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循环使用递归?

I am looking for a way to code a program which will multiply an integer to an exponent using only a recursion loop. I have a very limited understanding of recursion, but have been able to code something to give a factorial:

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

I have a way to find a power already, but it uses a for loop:

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

How can I replace this for loop using recursion?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

余生再见 2024-10-13 04:16:37
int my_power (int x, int e) {
  if (e == 0) return 1;

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

  return x * my_power(x, e-1);
}
分開簡單 2024-10-13 04:16:37

请记住,递归函数会调用自身,直到实现某些基本情况。您的基本情况是什么?计算一个数的幂就像说你要乘以某个数 x 次。提示是调用递归函数,将幂减一,直到达到所需的基本情况。

Remember that a recursive function calls itself until some base case is achieved. What is your base case here? Raising a number to a power is liking saying that you are going to multiply some number x amount of times. The hint is to call the recursive function, reducing the power by one until you reach your desired base case.

满天都是小星星 2024-10-13 04:16:37

使用戴夫·安德森(Dave Anderson)作为基础,但也要考虑以下特殊情况:

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

Use Dave Anderson's as a basis, but also consider the special cases of where:

1) x is 0 
2) e is negative.

Again, no code so you can try to figure it out yourself :-)

Update: Make sure you create a number of test cases, and you make sure everyone works as you think it should. Once the tests pass, you'll know that your recursive power function is working correctly.

Example: Having had time to figure it out yourself, I though I'd present a solution, with tests:

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;
}

Output:

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
南冥有猫 2024-10-13 04:16:37

做你想做的事情的正确方法是注意:

  • xn = (xn/2)2,如果 n 是偶数
  • x n = x * (x⊦n/2⫞)2,如果 n 为奇数
  • x1 = x
  • x0 = 1

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

与阶乘相反,阶乘为

  • n! = n * (n - 1)!,如果 n > 0
  • 0! = 1

您应该能够编写一个基于阶乘的递归程序来求幂。

The right way of doing what you want is by noticing that:

  • xn = (xn/2)2, if n is even
  • xn = x * (x⊦n/2⫞)2, if n is odd
  • x1 = x
  • x0 = 1

where "⊦n/2⫞" means the integer part of n/2 (which is what n/2 gives you in C when n is an integer variable).

Contrasting with the factorial, which reads

  • n! = n * (n - 1)!, if n > 0
  • 0! = 1

you should be able to write a recursive program for exponentiation basing yourself on the factorial.

鹤仙姿 2024-10-13 04:16:37

有一种思考这个问题的方法需要我们走出C-land,但它的核心如此简单且强大,非常值得考虑。

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

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

a,顺便说一句,被称为“累加器”,因为它累积每个“循环”的值)

您可能会感到陌生的一件事是,上面将函数视为任何其他数据类型,这就是所谓的“一流函数"。这通常不是您在 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 的)更省时。

There's a way of thinking about this that requires us stepping outside of C-land, but it's so simple at it's heart and powerful it's well worth considering.

Recursion and iteration aren't so different as they first seem. At a certain level, it's actually hard to tell them apart. We won't quite go there, but consider this recursive implementation of a for "loop" (in no particular language):

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

(The a, by the way, is called an "accumulator", because it accumulates the value of each "loop")

The one thing that might be new to you is that the above treats functions like any other data type, which is something called "first-class functions". This isn't typically something you do in C (you can do it in a limited fashion by passing function pointers), but it's so powerful a concept that it's well worth learning.

Using the above definition of for, we write your factorial function as:

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

This putts along, multiplying each i by the accumulator.

Another powerful concept (that, sadly, C doesn't support at all) is anonymous functions, which are simply functions created without names. I'm going to use the syntax e -> ... for anonymous functions, where ... is some expression (e.g. x -> x+1), and (a,b) for a pair of variables. In C, anonymous functions might seem useless, but if you can pass around functions as easily as you can pass around numbers, you can simplify fac to a single line:

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

pow can be written as:

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

Expand for in that, and you've got a recursive definition for pow.

Though this gives you a recursive function, there is another implementation (Alexandre's, in fact) that's more time efficient.

甜妞爱困 2024-10-13 04:16:37

据我所知,此函数对于任何可能的情况(不太可能将“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));
    }
}

This function will, to the best of my knowledge, for any likely case (someone setting "asdfj" as x or e is not likely) work.

#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));
    }
}
ˉ厌 2024-10-13 04:16:37

这是给您的伪代码:

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

Here's a pseudo-code for you:

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))

And oh, the return value should be double.

Here's the actual code:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文