有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前 20 项之和
有一分数序列: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.代码以及运行结果截图
方法一:
方法二:
运行结果截图: