erlang雜記十二--再說尾遞歸

翻了一下list模塊,看的時候,突然發現,尾遞歸其實是很容易展開成循環的。

想起讀書時剛開始學程序,C語言,一直再糾結的一個問題,就是如何讓一個函數返回兩個參數的結果,哈哈,不要笑我。

do_sth([], [], SA, SB)->{SA, SB};
do_sth([HA|TA]=LA,[HB|TB]=LB, SA, SB)->
        do_sth(TA, TB, HA+SA,HB+SB).

用erlang隨便寫了一個尾遞歸的函數,實現了對列表的一種計算

struct{int sa, int sb} do_sth(vector<int>:::iterator la, vector<int>::iterator lb, int sa, int sb){
    if(...){
        do_sth(....)
    }else{struct{sa, sb}};
}

翻譯成C++大概就是這個樣子,代碼寫的很醜= =。


我覺得看尾遞歸代碼的時候,就當他是循環,就很容易看了,終止條件就是else,其它就計算完後重新執行自己這個函數。

寫尾遞歸也是這個思路,else上面的代碼就把事情做完,else下面的代碼就只做最後的清理,整理一下就是尾遞歸了。。


我覺得尾遞歸有一個特點,就是把中間值傳到下一層遞歸裏面去了,就是第三第四個參數,

一般C++寫的遞歸是把中間值返回到上一層調用,然後繼續計算,然後再把結果返回上一層調用。

這種區別就使得一般的C++代碼一定要有個調用棧才能保證程序的正確性,如果把本層的計算結果傳入到下一層進行計算,那麼這個調用棧就不需要了,

就像完成了一次goto的過程。


即尾遞歸的計算順序與遞歸是相反的。

發佈了75 篇原創文章 · 獲贊 2 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章