由翻轉字元竄再次理解遞迴

2021-07-23 11:30:41 字數 1469 閱讀 3030

要求:輸入乙個字串,字串反序輸出。

比如:」hello」 ⇒ 「olleh」

首先就看**是什麼:

#include 

#include

using

namespace

std;

string str;

void reverse(int n) // 遞迴翻轉字串

}int main()

通過這種較為偏向硬體的說法,來解答演算法設計中遞迴的呼叫問題。

比如這裡,第一次進入的是reverse(0),進入後判斷0小於整個string的大小,因此將進入呼叫自身的指令。注意,此時不能就這樣走了,還得暫存當前指令後面的那條指令位址,整個指令就是:

cout << str[n];

也就是輸出當前下標為n的字元。但是現在還不能輸入,得等到自己對自己的探險結束後才回來輸出。

遞迴呼叫像是盜夢空間中的夢中夢,而且這個夢中夢可以不止僅僅只有三層!

如此想象:第一次進入夢境,為了回到現實,需要在這個夢後面留個鉤子,以從上一層夢境中跳出來。這就需要儲存起來,我們用的是棧,看重的是它後入先出的特性。當你進入夢境最深層想回來你是不是得完成最深的那個夢境,雖然最深的夢境是最後進入的卻最先完成。

進入第一層夢境後,把回到現實的位址存在了棧中,開始第一層夢境,然後發現條件滿足還可以進入下一層夢境,於是深入第二層。當然你可不想困在第二層夢境中出不來,於是在第一層夢境的入口邊上也做個標記,並把位址儲存到棧頂。如此繼續,直到最深層。

最深層執行時發現不能再進入更深了,於是該回去現實了。能一步跨回到現實嗎?隔著那麼多層夢境呢!飯要一口一口吃,一次只能回去一層。怎麼回去?借用棧。

這個時候一看棧頂,好,這是下一步可以去的地方,把這個位址寫入pc(程式計數器),順利回到上一層夢境,這一層的夢境並未執行完畢,因此繼續執行剩下部分。到這層夢境的尾聲了,這層夢境順利結束,下一步去**?看棧頂位址。跳到棧頂指示的位置開始執行再上一層的夢境的剩下部分。如此迴圈,直到靠近現實的那場夢境,再到回到現實,執行完現實的最後部分。棧已經空了,現實也結束。

這裡只說到儲存下一步的位址,實際上不止,會儲存當前步驟的所有資訊,我們稱之為保護現場,比如現實中reverse(0),輸出下標為0的字元,這個0就要被儲存到暫存器,用來最終完成現實的剩下部分。

講這麼囉嗦,純粹是因為,遞迴的思想太重要了。這不是我們記住全排列,翻轉斐波那契數列,甚至是漢諾塔的解法就ok,行走江湖就不怕了,不是這樣的。不理解執行的步驟推移,很難體會這種資料的遊走過程。

雖然我支援設計演算法時將這個部分忽略,關注頂層設計就好,要專注於當前任務,分而治之會更優雅,但絕不意味著不該仔細思考背後的硬體操作。

就像前幾天寫二叉樹的遞迴插入設計,我用bst去接下一層遞迴的返回位址,總是得不到正確的結果,單步跟蹤才理解用bst->left或者bst->right去接下一層呼叫的根一樣。

你不理解資料的流動過程,便沒有底氣說,我這麼設計就是對的。

以上。

由乙個翻轉字串程式看遞迴

大夥都知道遞迴就是乙個函式自己呼叫自己,可是對於遞迴的過程我總是很迷惑。今天正好看到乙個程式,就拿來仔細分析分析。includevoid reverse const char const sptr 將字串反著輸出 else int main void 這是乙個讓我們輸入字串,再對字串翻轉輸出的程式。...

遞迴系列2(字串翻轉,12345翻轉)

編寫乙個函式reverse string char string 遞迴實現 實現 將引數字串中的字元反向排列。要求 不能使用c函式庫中的字串操作函式。includevoid reverse string char string else return int main 把12345翻轉成54321 ...

C語言遞迴實現字串翻轉

一,c語言遞迴實現字串逆轉 簡單的實現 abc 的逆轉 函式原型 void reverse char value,char result char value為待逆序字串 char result為存放的逆序結果 1,首先判斷是否value是否為空和value是否是字串結尾條件 條件不滿足則retur...