本题要求实现一个计算Fibonacci数的简单函数,并利用其实现另一个函数,输出两正整数m和n(0<m≤n≤10000)之间的所有Fibonacci数。所谓Fibonacci数列就是满足任一项数字是前两项的和(最开始两项均定义为1)的数列。
函数接口定义:
int fib( int n );
void PrintFN( int m, int n );
其中函数fib
须返回第n
项Fibonacci数;函数PrintFN
要在一行中输出给定范围[m
, n
]内的所有Fibonacci数,相邻数字间有一个空格,行末不得有多余空格。如果给定区间内没有Fibonacci数,则输出一行“No Fibonacci number”。
#include <stdio.h>
int fib( int n );
void PrintFN( int m, int n );
int main()
{
int m, n, t;
scanf("%d %d %d", &m, &n, &t);
printf("fib(%d) = %d\n", t, fib(t));
PrintFN(m, n);
return 0;
}
/* 你的代码将被嵌在这里 */
我的代码:
int fib( int n ) {
if(n > 0){
int item[n+1] ;
//虚拟的把第一个数据变为0 解释第二个数据为1
for(int i = 0; i < n + 1; i++) {
item[i] = 0;
}
item[1] = 1;
int result = 1;//负责判断是否到达要求的数据了
for(int i = 2; ++result; i++) {
if(n == 1)break;
else {
item[i] = item[i-1] + item[i-2];
if( result == n) break;
}
}
return item[n];
}
else return EOF;
}
void PrintFN( int m, int n ) {
int judgl = 0, i = 1, item, black = 0;
do {
item = fib(i);
if(item >= m && item <= n) {
printf("%d",item);
judgl = 1;
black = 1;
}
if(black == 1 && fib(i+1) <= n) {
printf(" ");
}
i++;
} while(fib(i) <= n);
if( !judgl ) {
printf("No Fibonacci number");
}
}
真是又臭又长,令人感到难过。
fib函数,使用了数组:优点:容易理解;缺点:容易数组越界,空间浪费。
PrintN函数:多次调用fib函数,造成时间的浪费。
比较好的代码:
int fib(int n) {
if (n <= 2) {
return 1; // 对于第1和第2项直接返回1
}
int n1 = 1, n2 = 1, n3;
for (int i = 2; i < n; i++) {
n3 = n1 + n2;
n1 = n2;
n2 = n3;
}
return n2;
}
void PrintFN(int m, int n) {
int i = 1, fibValue;
int flag = 0; // 标记求得的斐波那契数
int blank = 1; // 控制字符前面是否带空格,标记为真,方便输出不带空格的第一个数
while (1) {
fibValue = fib(i);
if (fibValue < m) {
i++;
continue; // 如果当前斐波那契数小于m,增加i继续下一个数
}
if (fibValue > n) {
break; // 如果当前斐波那契数大于n,终止循环
}
// 处理空格并输出斐波那契数
if (blank) {
printf("%d", fibValue);
blank = 0; // 之后的输出需要前置空格
} else {
printf(" %d", fibValue);
}
flag = 1;
i++;
}
if (flag == 0) {
printf("No Fibonacci number");
}
}
优点:
fib函数:没有使用数组,尽管增加了理解难度,但的确减少了时长
PrintN函数:利用了更通俗易懂的方式来判断数据之间的空格输出
只调用了一次fib函数,循环结束方式理解也简单