有一分數序列:2/1,3/2,5/3,8/5,13/8,21/13...求出這個數列的前 20 項之和。
A.兩個關鍵
1該數列的求和的范圍是什么?
答:前二十項
2.最終的結果以及參與運算的值應該用什么數據類型表示?int嗎?
老哥,int類型的數據在整數除法運算中會有大量的損失(因為int類型的數據參與除法運算中不會保留余數),很顯然這樣做是不合理的,所以你應該采用float類型或者double類型來保存這些相關數據。
友情提示:float類型賦值時需要加f或F.如float=3.4f(本題的兩種方法均采用double類型的變量存放數據)
3.該數列有何規律?
第一種規律:
把分子、分母分開看,就易知道分子、分母都滿足f(n)=f(n-1)+f(n-2)(n>=3)的公式
該公式的通俗理解是:無論是分子還是分母,從第三項起,每一項都等於其前面兩項之和,如5=2+3,8=3+5(分子);1+2=3,2+3=5(分母)。
第二種規律:
把分子分母放在一起看就有如下結論:
從第二項起,每一項分子=前一項的分子+前一項的分母。(如第二個數中的3=2+1)
每一項的分母=前一項的分子(如:第二個數中的分母3與第一個數的分子3是滿足數值一樣的規律)。
根據數列規律的不同,可以將其分為兩種不同的解法
方法一(單看分子、分母法)
注:p[]是用來專門存放分子的,q[]是用來專門存放分母的。
核心算法思想:從第四項起,每循環一次,都要先找出該項(第i項)的前兩項的分子,然后把它們的和放入p[i]中,再找出該項(第i項)前兩項的分母,然后把它們的和放入q[i]中。這樣該項(第i項)的分子、分母就分別存放到了正確的位置了。
相應的代碼: if(p[i-1]>p[i-3]&&p[i-2]>p[i-3]){
p[i]=p[i-1]+p[i-2];
if(q[i-1]>q[i-3]&&q[i-2]>q[i-3]){
q[i]=q[i-1]+q[i-2];
}
}
方法二:(分子、分母皆看法)
注:a變量:專門存放分子;b變量:專門存放分母。
核心算法思想;替換。用變量t存放臨時的分子值(目的是傳遞給后一項作分母用),保證了a變成了后一項的分子時,變量b還能收到正確的分母值。
相應的代碼: sum=sum+a/b;
t=a;
a=a+b;
b=t;
4.總結方法一與方法二的優缺點
方法一;
優點:適用范圍更廣。需要滿足的條件:從第二項起,每一項的分子、分母分別等於前兩項的分子、分母之和
缺點:更耗內存,需要較多的運行時間。(理由:兩個數組依次接收了每一項的分子、分母,而且求和的項數不確定,導致了定義動態數組時需要盡量把數組的長度定義的多一些。)
方法二:
優點:代碼段較短,容易維護。運行速度更快。
缺點:想到該方法的時間較長。
其實,方法一的優點恰恰是方法二的缺點,方法一的缺點恰恰是方法二的優點。
B.代碼以及運行結果截圖
方法一:
方法二:
運行結果截圖: