1.什么是斐波那契数列
斐波那契数列 :因数学家莱昂纳多· 斐波那契 在1228年的《算经》修订版上载有如下“兔子问题:
如果每对兔子(一雄一雌)每月能生殖一对小兔子,每对兔子第一个月没有生殖能力,但从第二个 月以后便能每月生一对小兔子假定这些兔子都没有死亡现象,那么从第一对刚出生的兔子开始,12 个月以后会有多少对兔子呢?
一个月:只有一对兔子;第二个月: 仍然只有一对兔子;第三个月:这对兔子生了一对小兔子, 共有 1+1=2 对兔子.第四个月:最初的一对兔子又生一对兔子,共有 2+1=3 对兔子.则由第一个月到第十二个月兔子的 对数分别是:1,1,2,3,5,8,13,21,34,55,89,144, ……,后 人为了纪念提出兔子繁殖问题的斐波纳契, 将这个兔子数列称为斐波那契数列。
2.实现思路
想要解决这一问题要先从数列上找到一定的规律,我们来看:1,1,2,3,5,8,13,21……,这一数列是否从第三项开始就为前两项的和了呢?验证一下:2=1+1,3=2+1,5=3+2。规律找到了那我们怎么用代码来实现呢?
2.1递归实现
首先简单了解一下递归的思路:递归就是指函数直接或间接的调用自身,是一个复杂的问题变成规模更小的问题,有一个递归入口和递归出口。那怎么用递归来做这道题呢?我们来看假如要找第五项:
而我们已知斐波那契数列第一,第二项的值为1,只要我们拆分到1或者2拆分结束,开始把值返回。我们可以就此为递归出口来实现递归:每一项为前两项的和:
int fib(int x) {
if (x == 1 || x == 2) return 1;//如果为第一项或者第二项结束递,返回值
else return fib(x - 1) + fib(x - 2);//意为找到前两项的值
}
在主函数中调用输出即可。
2.2循环实现
首先要确定要找到第几项的值:
int f1 = 1, f2 = 1, f = 0; //f1为前两项,f2为前一项,f为第n项数列的值
int n,i;
printf("请输入:");
scanf("%d", &n);
再来考虑1,1,2,3,5,8,13,21......这个数列前两项都为1,那么输入n的值之后就要判断一下n是否为1或2,是的话输出1,从第三项开始数列的值就为前两项和,所以可以使用一个循环来从第三项开始计算到n项的值(第一第二项默认为f1,f2),循环更新前两项的值,最后输出。为了避免重复输出所以使用一个if else语句控制:
if (n == 1 || n == 2) //如果要寻找的是第一第二项那么直接输出1
printf("%d", 1);
else
{
for (i = 3; i <= n; i++) { //从第三项开始就为前两项的和
f = f1 + f2;
f1 = f2; //前两项的值更新,为下一个数列数字的前两项
f2 = f;
}
printf("%d", f);
}
3.完整代码
3.1递归代码
int fib(int x) {
if (x == 1 || x == 2) return 1;//如果为第一项或者第二项结束递,返回值
else return fib(x - 1) + fib(x - 2);//意为找到前两项的值
}
int main() {
int n;
printf("请输入:");
scanf("%d", &n);
printf("%d", fib(n));
return 0;
}
3.2循环代码
int main() {
int f1 = 1, f2 = 1, f = 0; //f1为前两项,f2为前一项
int n,i;
printf("请输入:");
scanf("%d", &n);
if (n == 1 || n == 2) //如果要寻找的是第一第二项那么直接输出1
printf("%d", 1);
else
{
for (i = 3; i <= n; i++) { //从第三项开始就为前两项的和
f = f1 + f2;
f1 = f2; //前两项的值更新,为下一个数列数字的前两项
f2 = f;
}
printf("%d", f);
}
return 0;
}
感谢大家的观看,如有错误请指正。