簡體   English   中英

遞歸函數導致堆棧溢出

[英]Recursive function causes stack overflow

我有以下任務:

編寫一個要求輸入數字和冪的程序。 編寫一個將數字取冪的遞歸函數。 例如,如果數字為2,冪為4,則函數將返回16。

我寫了一個程序,編譯時沒有錯誤,但是當我啟動程序並輸入一個值時,出現錯誤,提示“堆棧溢出”。 我想我的遞歸函數變成了無限,但我不知道如何用其他方式編寫它。

這是我的代碼:

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

您沒有遞歸的終止條件,因此它將永遠運行。

聽起來您可能對遞歸沒有很好的了解,所以我想從更簡單的斐波那契數列開始

每當我們根據遞歸定義函數時,都需要首先定義一個基本案例。 就斐波那契而言,我們有2個基本案例:

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

也就是說,用英語來說,“ F的0為0,F的1為1”。 更簡單地說,如果將0傳遞給函數F,我們將獲得0。 如果我們通過1,我們將得到1。

一旦定義了基本案例,就需要尋找一個遞歸關系。 對於斐波那契,我們有以下重復發生的情況:

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

因此,對於n >= 2 ,我們可以使用上述遞歸。 為什么? 好吧,讓我們嘗試n = 2。

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

因此,現在我們知道F(2)的答案為1。此外,我們現在可以計算F(3)的答案。 為什么? 那么,我們需要什么來計算F(3)? 我們需要F(2)和F(1)。 由於F(1)是基本情況,我們現在有了這兩個答案,而我們剛剛解決了上面的F(2)。

因此,現在讓我們嘗試編寫一段偽代碼來解決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);
}

請注意,在遞歸函數中,我們總是在函數開始時處理基本情況。 如果沒有適當的基礎案例,則無法定義此重復發生,否則,我們將沒有終止條件。 這就是為什么您總是將基本案例放在函數的開頭

現在,根據上述解釋,另一個好的練習是為階乘函數編寫一個遞歸函數 因此,請按照下列步驟操作:

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.

一旦掌握了這些步驟,那么繼續進行功率恢復對您來說就更有意義了。

您的職能

  • 沒有應該做什么
  • 沒有終止條件

嘗試考慮以下問題:當函數只接受一個數字作為參數時,如何返回x^y 然后,考慮如何將數字提高為冪,並且實現應該很明顯。

遞歸例程始終需要“平凡”或“基本”的情況。 想想您寫的內容,將1傳遞給x,什么將阻止遞歸?

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

adinfinitum(或直到您退出堆棧)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM