C語言遞迴解決年齡問題
問題描述有5個人坐在一起,問第5個人多少歲,他說比第4個人大2歲。問第4個人多少歲,他說比第3個人大2歲。問第3人多少歲,他說比第2個人大2歲。問第2個人多少歲,他說比第1個人大2歲。最後問第1個人,他說他是10歲。編寫程式,當輸入第幾個人時求出其對應的年齡。
問題分析
該問題是一個遞迴問題。要求第5個人的年齡,必須先知道第4個人的年齡,顯然第4個人的年齡也是未知的,但可以由第3個人的年齡推算出來。而想知道第3個人的年齡又必須先知道第2個人的年齡,第2個人的年齡則取決於第1個人的年齡。
又已知每個人的年齡都比其前一個人的年齡大2,因此根據題意,可得到如下幾個表示式:
age(5)=age(4)+2
age(4)=age(3)+2
age(3)=age(2)+2
age(2)=age(1)+2
age(1)=10
求解第n個人的年齡分成兩個階段。第一個階段是“回推”過程,第二個階段是“遞推”過程。
在“回推”過程中,利用的是n>1時的公式age(n-l)+2。要求的是第n個人的年齡,因此首先將第n個人的年齡回推到第n-1個人的年齡,但第n-1個人的年齡仍然未知,因此需要繼續回推到第n-2個人的年齡,第n-2個人的年齡仍然未知,需要繼續向前回推,如此下去,一直回推到第1個人的年齡。而第1個人的年齡是已知的,因此,第一階段的 “回推”結束。
在“遞推”過程中,從第1個人的年齡可以推出第2個人的年齡,從第2個人的年齡可以推出第3個人的年齡,如此下去一直遞推到第5個人的年齡。
演算法設計
理解了問題分析中的遞迴處理過程後,演算法設計就非常簡單了。只需要將公式轉換成一個函式,然後用main()函式呼叫它就可以了。
下面是完整的程式碼:
#include<stdio.h> int age(int n) { int x; if(n == 1) x=10; else x=age(n-1)+2; return x; } int main() { int n; printf("請輸入n值:"); scanf("%d", &n); printf("第%d個人的年齡為%d\n", n, age(n)); return 0; }
執行結果:
請輸入n值:5
第5個人的年齡為18
知識點補充
由該題的分析過程可知,遞迴的問題都可以分為“回推”和“遞推”兩個階段。而且必須存在一個能夠結束遞迴過程的條件,如本題中的age(l)=10,否則遞迴過程會無限制地進行下去而無法結束。
下面對遞迴法做下總結。
遞迴是設計和描述演算法的一種強有力的工具。能夠釆用遞迴來描述的演算法通常具有如下的特徵:為求解規模為n的問題,首先要將它分解成規模較小的問題,然後通過這些小問題的解,能夠方便地構造出大問題的解。
同時,這些規模較小的問題也能夠採取同樣的分解方法分解成規模更小的問題,並能夠通過這些更小的問題的解構造出規模較大的問題的解。特別地,當問題規模n=0或n=1時,能直接獲得問題的解。
遞迴演算法的執行過程分為“回推”和“遞推”兩個階段:
- 在回推階段,是把較複雜的問題(規模為n)的求解遞推到比原問題簡單一些的問題(規模小於n)的求解。例如本例中,要求解age(n),先把它遞推到求解age(n-l),而要計算age(n-1),又必須先計算age(n-2),依次類推,直到計算age(1)為止。需要注意的是,在遞推階段,必須要有能夠終止遞迴的條件。如本例中n為1時,遞推可終止。
- 在遞推階段,當獲得最簡單情況的解時,如本題中得到age(1)的值,逐級返回,依次得到較複雜問題的解,最終獲得所求問題的解。
在編寫遞迴函式時需要注意,函式中定義的區域性變數和形式引數只在當前的呼叫層有效,當回推到簡單問題時,原來呼叫層中的區域性變數和引數都被隱藏起來。每一個簡單問題層中都有自己的區域性變數和引數。
Linux公社的RSS地址 : ofollow,noindex" target="_blank">https://www.linuxidc.com/rssFeed.aspx
本文永久更新連結地址: https://www.linuxidc.com/Linux/2018-10/154998.htm