版权声明:转载请注明出处 https://blog.csdn.net/Rosemary_tu/article/details/83619025
本文是对西安交通大学C++慕课第三章编程练习的16题的讲解。
参考博客:https://blog.csdn.net/zombie_slicer/article/details/38871799
题目内容:
编写程序,显示Fibonaci序列的前n项(从0开始)。
F(0)=0 F(1)=1 F(n)=F(n-1)+F(n-2)
输入:非负整数n
输出:n+1个整数,数据间有一个空格,末尾无空格。
【提示】
样例1输入:
10
样例1输出:
0 1 1 2 3 5 8 13 21 34 55
时间限制:500ms 内存限制:32000kb
Fibonaci数列:
当输入正整数n为0或1时,f(0)=0,f(1)=1;当n大于1时f(n)=f(n-1)+f(n-2)。
一种非常简单的实现方式是通过递归算法:
int function(int n)
{
if (n == 0)
{
return 0;
}
else if (n == 1)
{
return 1;
}
else if(n>=2)
return function(n - 1) + function(n - 2);
}
通常来说,听到Fibonaci首先想到的就是递归,但是这并不能说明递归最适合这个题目。例如,要算f(10), 首先要分别求f(9)和f(8);同样,要算f(9),就得先算f(8)和f(7); 以此类推…
利用递归算法求Fibonaci数列会出现大量的重复计算,把这个结构画成二叉树,可以看出当n越大,重复的节点数将急剧增大,计算量也因此大大增加,实际上,此算法的时间复杂度是以n的指数的方式增加的。
比如这道题目限制程序运行时间在500ms 以内,使用递归算法求解就会出现运行超时的错误 (亲测)。
另一种实现方式是通过循环的方式。
大致思想为:从底到上计算,即先根据f(0)和f(1)计算出f(2),再通过f(1)和f(2)计算出f(3),以此类推,直到f(n)为止。从而避免大量的重复计算,其时间复杂度为O(n)。代码如下:
int function(int n)
{
long long first = 0;
long long second = 1;
long long sum = 0;
if(n<=1){
return (n==1)? 1:0;
}
for(int i=2; i<=n;i++){
sum = first + second;
first = second;
second = sum;
}
return sum;
}
本题的完整代码如下:
#include<iostream>
#include<stdlib.h>
using namespace std;
int function(int n);
int main()
{
int i,n;
cin >> n;
for (i = 0; i <= n; i++)
{
cout << function(i);
if (i < n)
{
cout << " ";
}
}
cout << endl;
return 0;
}
int function(int n)
{
long long first = 0;
long long second = 1;
long long sum = 0;
if(n<=1){
return (n==1)? 1:0;
}
for(int i=2; i<=n;i++){
sum = first + second;
first = second;
second = sum;
}
return sum;
}