小蜜蜂问题|函数迭代V.S.函数递归|斐波那契数列|字符串加法(略)

一.函数迭代V.S.函数递归

1.函数调用

2.函数迭代

3.函数递归

4.函数迭代与函数递归——相同点

5.函数迭代与函数递归——不同点

二.小蜜蜂问题

1.算法分析

2.斐波那契数列

3.字符串加法(略)


一.函数迭代V.S.函数递归:

最近学函数很大的感想是:一听讲解就恍然大悟,一自己做就不知如何排布。

什么是函数调用?什么是函数迭代?什么是函数递归?学的时候似乎分得很清,但是一做题就容易思维混乱,开始迭代递归混搭使用......

今天由小蜜蜂这题,我对迭代和递归有了些新的认识和感受,比较直观条目化,可以有效摆脱抽象,所以与大家分享~


1.函数调用:

通过函数语句,来抽调使用一个定义过的函数;


2.函数迭代:

2.1 本质:

通过循环的方式,来模拟递归的过程(可以理解为通过循环赋值的方式来达到递归的效果),但不是递归本身;

所以不应该在循环里再去调用函数自身,否则仍是一种不完全的递归,也许会减少一些重复劳动,但仍不能使效率有质的提升;

一定要思路清晰,避免递归、迭代混搭!

2.2 终止条件:

取决于循环的终止条件;

2.3 过程:

①必要的分类讨论(通过选择语句实现);

②主体部分:不断赋值给变量(需要能够找出普适的规律和普适的赋值方式)

+对变量进行完全相同步骤的重复(通过循环语句实现)

+返回最后一次循环的结果;

③其他部分:是一些特殊情况,通常比较简单,各自返回计算结果即可;


3.函数递归:

3.1 本质:

通过不断调用函数的方式,大事化小(自己找规律)/公式法(现成,较简单),

最终化为一种最简单的情况(进入另一分支),返回确定的值,

再由此层层返回至所求的情况;

也一样不要再嵌套循环,造成与迭代混搭的混乱写法;

3.2 终止条件:

将最简单的情况作为一个单独的分支,返回确定的值,

不断调用,最终一定会化为这种情况,从而终止;

3.3 过程:

①分类讨论,分出主体部分,特殊情况和最简单的情况(用于终止递归)

(通过选择语句实现);

②主体部分:找出相邻两数间的关系,在return后表达出来(通过函数调用实现+return实现)

+不断调用至最简单的情况,返回确定的值;

+从而层层返回确定的值,最终返回一个确定的结果;

③其他部分:是一些特殊情况,通常比较简单,各自返回计算结果即可;


4.函数迭代与函数递归——相同点

① 都需要终止条件;

② 都是为了实现一种递归思想;


5.函数迭代与函数递归——不同点

① 迭代——循环,不调用;

递归——调用,不循环;

② 迭代——主体部分返回最后一次循环的结果;

递归——主体部分有最简单的情况的确定的返回值,根据调用,逆向层层返回,得到确定结果;

③ 迭代--效率高,不重复劳动,但是有时难以实现,没有递归的思路简单;

递归--效率低,但思路简单,不能递归层次过深,会造成栈溢出;


二.小蜜蜂问题:

1.算法分析:

斐波那契数列+字符串加法


2.斐波那契数列:

  • 其本质为斐波那契数列,只是描述的花哨;

  • 斐波那契数列解释:

  • 代码实现(两种方式):

  1. 函数迭代:(效率高,但因为循环是完全相同的步骤的重复,就需要能够找出普适的规律和普适的赋值方式)

#include <stdio.h>

long long route(int a, int b)
{
	int i;
	long long count = 2, tmp = 1,copy;
	if (b == a + 1)
	{
		return 1;
	}
	else if (b == a + 2)
	{
		return 2;
	}
	else
	{
		for (i = a + 3; i <= b; i++)//主体部分(函数迭代);
		{
			copy = count;
			count = count + tmp;
			tmp = copy;
		}
		return count;
	}
}

int main()
{
	int a, b;
	scanf("%d %d", &a, &b);
	long long route_count = route(a, b);
	printf("%lf\n", route_count);
	return 0;
}

2.函数递归:(很直接,但是效率低,e.g.1-50那个测试用例要运行大约两分钟)

#include <stdio.h>

long long route(int a, int b)
{
	if (b == a + 1)
	{
		return 1;
	}
	else if (b == a + 2)
	{
		return 2;
	}
	else
	{
		return route(a, b - 1) + route(a, b - 2);
	}
}

int main()
{
	int a, b;
	scanf("%d %d", &a, &b);
	long long count = route(a, b);
	printf("%lld\n", count);
	return 0;
}

效率低的原因分析:

3.迭代递归混搭(本质还是递归)

是思维极度混乱的产物,要摒弃!!!

#include <stdio.h>
long long route(int a, int b)
{
	int i;
	long long count = 2;
	if (b == a + 1)
	{
		return 1;
	}
	else if (b == a + 2)
	{
		return 2;
	}
	else
	{
		for (i = a + 3; i <= b; i++)
		{
			count = count + route(a, i - 2);
		}
		return count;
	}
}

3.字符串加法:

需使用的理由:因为测试用例1-100那个的结果数字过大,超过了long long型,错误截图如下

具体做法(略)

大佬的分析

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值