用递归解决一些问题

本文深入浅出地介绍了递归的概念,通过strlen的递归实现、字符数组逆置的递归方法及菱形打印的递归案例,详细阐述了如何将复杂问题分解为相似子问题并考虑边界条件。递归作为一种强大的编程技巧,能够简化问题解决的逻辑,提高代码的可读性。
摘要由CSDN通过智能技术生成

1.浅谈递归的理解
有时候,对于一个复杂问题的求解,我们可以考虑通过一些步骤,将复杂的问题转化成规模变小的相同问题进行求解。最后一层一层传递下去,只要我们解决了规模最小的、不可再分解的问题后,逐级回溯也就解决了规模较大的复杂问题。
学会递归,就是学会分解,在我看来就是要学会将问题的求解分步拆解,并考虑周全。
什么叫拆解成类似的子问题呢?比如有一个问题叫做跑100米,我们可以将其分步进行:先跑10米,再解决子问题:跑90米,这样我们就成功地将问题的规模从跑100米,缩小成了跑90米。而父子问题都是类似的,都是要解决跑n米的问题,只不过是规模缩小了罢了。至此,我们实现了复杂问题的拆解。但我们还需要考虑周全,试想我们每次分步进行都能将问题的规模减少个10米,但是当我们最后拆到了需要解决跑0米这个问题的时候,我们还能按照之前的方式分步进行吗,(即先走10米,再解决跑-10米的问题),显然不对的,所以我们要为这个不满足我们分步拆解的情况单独处理。也就是要求当跑到0米的时候,我们就停止,而不是继续拆分。这就是考虑周全。
2.一些实例(to be continued)
1.strlen的递归实现(自定义的strlen命名为my_strlen)
分步思路:计算一个首地址为string的字符串长度,可以先算第一个字符,再计算这个字符以后的字符串长度。也就是my_strlen(string)返回的值等于1+my_strlen(string+1)。然后考虑周全,如果是my_strlen处理的字符串就是\0呢,所以我们要求如果是这个情况,则这个函数返回0。
代码实现:

int my_strlen(char *string)
{
	if (*string)
		return 1 + my_strlen(string + 1);
	else
		return 0;
}

2.字符数组内容逆置的递归实现(逆置函数命名为reverse)
分步思路:这次相对复杂些。考虑一个字符数组string内容为:abcdefg\0
首先第一步,将bcdefg\0这个字符数组逆置,即reverse(string+1),然后将a移到\0前面(具体实现可以通过与a右边的字符交换位置,直到遇到\0停止)。然后考虑周全,当处理的字符串长度只有1的时候,就无法按照前面那样分步了,此时我们不做处理。
代码实现:

void reverse(char string[])
{
	if (*(string + 1))
	{
		reverse(string + 1);
	}
	while (*(string + 1))
	{
		char temp = *string;
		*string = *(string + 1);
		*(string + 1) = temp;
		string++;
	}
}

3.打印菱形的递归实现(自定义函数命名为print)
(首先明确该问题完全没必要用递归,此处只不过为了演示分步的方法)
打印出来的菱形大概长这样:
在这里插入图片描述
分步思路:将print(n)看成是打印第一行和最后一行有n个星的"菱形"(中间为13个星),则打印如图的菱形分步走的话就是先打印第一行的(13-1)/2个空格和1个星,然后打印print(2),再打印最后一行的(13-1)/2个空格和1个星。对于print(n)就相当于先打印第一行(13-n)/2个空格和n个星,然后再打印print(n+1),然后再打印最后一行的(13-1)/2个空格和n个星。考虑特殊情况,当n已经等于13,即最中间的星星数的时候,显然无法用上面的情况将其分解了,此时就只打印中间的13个星。
代码实现:

void print(int n)
{
	int i;
	for (i = 0; i < (13 - n) / 2; i++)
		printf(" ");
	for (i = 0; i < n; i++)
		printf("*");
	printf("\n");
	if (n != 13)
	{
		print(n + 2);
		for (i = 0; i < (13 - n) / 2; i++)
			printf(" ");
		for (i = 0; i < n; i++)
			printf("*");
		printf("\n");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值