简体   繁体   English

递归函数导致堆栈溢出

[英]Recursive function causes stack overflow

I have the following task: 我有以下任务:

Write a program that asks for a number and a power. 编写一个要求输入数字和幂的程序。 Write a recursive function that takes the number to the power. 编写一个将数字取幂的递归函数。 For example, if the number is 2 and the power is 4, the function will return 16. 例如,如果数字为2,幂为4,则函数将返回16。

I wrote a program and there are no errors when I compile it, but when I start the program and enter a value gives an error saying "Stack Overflow". 我写了一个程序,编译时没有错误,但是当我启动程序并输入一个值时,出现错误,提示“堆栈溢出”。 I suppose my recursive function became infinite but I have no idea how to write it in other way. 我想我的递归函数变成了无限,但我不知道如何用其他方式编写它。

This is my code: 这是我的代码:

#include <iostream>
using namespace std;
int powpow(int number);

int main(){
    cout<<"Enter number:";
    int x;
    cin>>x;
    cout<<"The result of ("<<x<<" * "<<x<<") * "<<x*x<<" is: "<<powpow(x);
    system("pause");
    return 0;
}
int powpow(int number){
    int result = number*number;
    return powpow(result);
}

You have no terminating condition for your recursion, so it runs forever. 您没有递归的终止条件,因此它将永远运行。

It sounds like maybe you don't have a good grasp of recursion, so I'd like to start with something a little simpler, the Fibonacci sequence . 听起来您可能对递归没有很好的了解,所以我想从更简单的斐波那契数列开始

Any time we define a function in terms of recursion, we need to first define a base case(s). 每当我们根据递归定义函数时,都需要首先定义一个基本案例。 In the case of Fibonacci, we have 2 base cases: 就斐波那契而言,我们有2个基本案例:

F(0) = 0
F(1) = 1

That says, in english, "F of 0 is 0, F of 1 is 1". 也就是说,用英语来说,“ F的0为0,F的1为1”。 Or even more simply, if we pass 0 to function F, we will get 0 back. 更简单地说,如果将0传递给函数F,我们将获得0。 If we pass 1, we will get 1 back. 如果我们通过1,我们将得到1。

Once we have the base cases defined, then we need to look for a recurrence relation. 一旦定义了基本案例,就需要寻找一个递归关系。 In the case of Fibonacci, we have the following recurrence: 对于斐波那契,我们有以下重复发生的情况:

F(n) = F(n-1) + F(n-2) F(n)= F(n-1)+ F(n-2)

So for n >= 2 , we can use the above recurrence. 因此,对于n >= 2 ,我们可以使用上述递归。 Why? 为什么? Well, lets try it for n = 2. 好吧,让我们尝试n = 2。

F(2) = F(n-1) + F(n-2)
     = F(1) + F(0)
     = 1    + 0
     = 1

So now we know that the answer to F(2) is 1. And what's more, we can now compute the answer to F(3). 因此,现在我们知道F(2)的答案为1。此外,我们现在可以计算F(3)的答案。 Why? 为什么? Well, what do we need to compute F(3)? 那么,我们需要什么来计算F(3)? We need F(2) and F(1). 我们需要F(2)和F(1)。 We now have both of those answers since F(1) is a base case, and we just solved F(2) above. 由于F(1)是基本情况,我们现在有了这两个答案,而我们刚刚解决了上面的F(2)。

So, now let's try to write a piece of pseudo code to solve F. 因此,现在让我们尝试编写一段伪代码来解决F。

function F(int n) {
  // handle base cases
  if (n equals 0)
    return 0
  if (n equals 1)
    return 1

  // recurrence
  return F(n-1) + F(n-2);
}

Note that in a recursive function, we always handle the base cases at the beginning of the function. 请注意,在递归函数中,我们总是在函数开始时处理基本情况。 We cannot define this recurrence if we don't have base cases in place, otherwise, we will have no terminating condition for our recurrence. 如果没有适当的基础案例,则无法定义此重复发生,否则,我们将没有终止条件。 So that's why you always put the base cases at the beginning of the function. 这就是为什么您总是将基本案例放在函数的开头

Now, given the above explanation, another good exercise would be to write a recursive function for the factorial function . 现在,根据上述解释,另一个好的练习是为阶乘函数编写一个递归函数 So, follow these steps: 因此,请按照下列步骤操作:

1. Define the base case (use wikipedia article for hints).
2. Define recurrence in terms of base case
3. Write pseudo code to solve the recurrence, and be sure to put base case(s) at beginning of function, and recurrence at end.

Once you grasp these steps, then moving on to the power recurrence should make much more sense to you. 一旦掌握了这些步骤,那么继续进行功率恢复对您来说就更有意义了。

Your function 您的职能

  • does not what it should do 没有应该做什么
  • has no termination condition 没有终止条件

Try to think about this: How can your function return x^y when it only takes one number as a parameter. 尝试考虑以下问题:当函数只接受一个数字作为参数时,如何返回x^y Then, think about how you raise number to a power and the implementation should be obvious. 然后,考虑如何将数字提高为幂,并且实现应该很明显。

Recursive routines always need a "trivial" or "base" case. 递归例程始终需要“平凡”或“基本”的情况。 Think about what you wrote, pass in 1 for x, what will the stop the recursion? 想想您写的内容,将1传递给x,什么将阻止递归?

powpow(1)
  result = 1*1
  call powpow(1)
    result = 1*1
    call powpow(1)
      result = 1*1
      call powpow(1)

adinfinitum (or until you exeed the stack) adinfinitum(或直到您退出堆栈)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM