C语言函数(12)--- 递归(4)
  uUWKQE7Avyk4 2023年11月02日 33 0

我们前一篇文章介绍了利用函数的递归来实现斐波那契数

代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<windows.h>
int Fib(int n){
	if (n <= 2){
		return 1;
	}
	else{
		return Fib(n - 1) + Fib(n-2);
	}
}
int main(void){
	int n = 0;
	int ret = 0;
	printf("请输入:");
	scanf("%d",&n);
	ret = Fib(n);
	printf("ret=%d\n",ret);
	return 0;
}

但是我们还有一个问题就是当我们输入一个50或者更加大的数字的时候程序就会出现卡死的情况,今天我们就来着重解决这个问题,首先我们再来熟悉一下什么是斐波那契数,说白了就是 当前值等于前两个数字的和,如 1 1 2 3 5 8,当我们输入一个数字的时候,程序便会去找这个数字的前面两个数,但是前面两个数字也是未知的,所以还需要倒推,如我们输入了一个50,程序就要执行下列的运算:

50  ---> 49 48
49  ---> 48 47
48  ---> 47 46
47  ---> 46 45
`````

我们可以发现,在程序计算的时候有很多的操作是重复在做的,这些重复的运算量是巨大的,我们以40为例,将代码修改成如下形式:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int count = 0;
int Fib(int n){
	if (n == 3){
		count++;
	}
	if (n <= 2){
		return 1;
	}
	else{
		return Fib(n - 1) + Fib(n-2);
	}
}
int main(void){
	int n = 0;
	int ret = 0;
	printf("请输入:");
	scanf("%d",&n);
	ret = Fib(n);
	printf("ret=%d\n",ret);
	printf("count=%d\n",count);
	return 0;
}

我们创建一个全局变量count来帮助我们计数,在Fib()函数中加入

if(n==3){
count++;
}

这个语句将会帮助我们计数程序重复计算的次数,最后在main()函数中输出count的值,如图所示:

C语言函数(12)--- 递归(4)_斐波那契数

我们可以看到仅仅是计算第40个斐波那契数,count变量统计到的重复运算次数就高达3900万次,随着用户输入的增大,重复的次数也将成指数倍增长,这也就是我们为什么输入更大一点的数字时候,程序会不响应,那有什么办法解决这个问题呢?

其实我们除了使用到递归还可以使用迭代,所谓迭代可以理解为重复的计算某一段代码,那么我们该怎么具体实现呢?

我们可以创建三个变量,这里使用a b c 作为变量名称,变量a与变量b用来存前两个斐波那契数,变量c用来存两数之和,算完之后我们将b的值放到a中,将c的值放到b中,如图所示:

C语言函数(12)--- 递归(4)_迭代_02

a b c为第一次计算时候的值,当计算完成后原先b的值被a取代,c的值被b取代,所以我们可以写一个while()循环,来循环执行上述步骤,如以下代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int Fib(int n){
	int a = 1;
	int b = 1;
	int c = 1;
	while (n > 2){
		c = a + b;
		a = b;
		b = c;
		n--;
	}
	return c;
}
int main(void){
	int n = 0;
	int ret = 0;
	printf("请输入:");
	scanf("%d",&n);
	ret = Fib(n);
	printf("ret=%d\n",ret);
	return 0;
}

c的值我们定为1,因为若c=0,当n的值小于等于2的时候则会跳过while()循环直接返回c的值,我们之前已经说过了,n小于等于2的时候应该返回1,所以将c的值确定为1是最好的,我们编译并运行上述代码,当我们再输入60的时候可以发现结果一下子就出来了,虽然结果可能是错误的,因为数字已经超过了int类型所能容纳的最大值,发生了溢出,如图所示:

C语言函数(12)--- 递归(4)_函数_03

                                                                                 2023/8/19

                                                                                        王起舟

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
uUWKQE7Avyk4