详解递归实现函数reverse_string(char* string)将字符串反向排序

实现:将参数字符串中的字符反向排列.
之前我们已经多次写过不利用库函数去求字符串长度,所以我们在这里再用一次,先把需要反向排序的字符串长度求出来,方便后面的使用

int Strlen(char* str){	//定义函数求字符串长度
	int i;
	//当str[i] = '\0'时跳出循环,此时i就是字符串的长度
	for (i = 0; str[i]; ++i);
	return i;
}	

求出字符串长度之后,接下来就是实现将字符串反向排序的函数,这才是这个题目的重中之重.
我们这样去思考,先假设我们要反向排序的字符串是"huanyinnin",现在我们要将它反向排序,那我们现在想要实现的其实就是把最后一个字符放到首位,首位的字符放到最后一位.这样就变成了"nuanyinnih",那么接下来呢?我们依然像前面那样交换就又换回来了,所以我们第二部是想ba"i"和"u"互换,那我们这样来思考,有没有办法在进行第二步的时候让字符串的首字符和最后一个字符就是我们需要交换的.
这里我们要先解释一个东西,str其实就是字符串首元素的地址,而
str + 1就是字符串的次元素地址.利用这个我们就可以实现这个函数了,先看这个函数代码

void reverse_string(char* string){
	int end = Strlen(string) - 1;
	char tmp = string[0];
	if (string[0]){
		string[0] = string[end];
		string[end] = '\0';
		reverse_string(string + 1);
		string[end] = tmp;
	}
}

在这个函数中,我们的思路是先将字符串的首元素字符赋给tmp,这样首元素的位置就空了出来,然后把尾元素赋给首元素,因为我们需要重复进行这样的过程,所以用if语句去判断str[0]是否为空,不为空就执行下去.
当我们将尾元素赋给首元素之后,我们不能直接把首元素直接赋给尾元素(也就是不能直接str[end] = str[0]),如果直接进行赋值的话,那每次交换的都会是首字母"h",所以我们想要的是:每次交换之后,不要上次交换的首尾字母,这也就对应了上面的代码(str[end] = ‘\0’),也就是说我们先把本来要放在尾部的字符先存起来,然后让最后一个字符变为空字符,这样第二次需要交换的就是"uanyinni",交换之后就变成了"ianyinnu".
注意我们在将str[end] = '\0’之后,反复调用了reverse_string这个函数,这就是递归思想的应用.知道上面代码的目的之后,我们来理清这个递归思路.
刚开始是"huanyinnin",将首元素存在tmp之中,尾元素赋给首元素变成"nuanyinnin",尾元素str[end] = ‘\0’,也就变成了"nuanyinni",接下来在调用reverse_string(str + 1),也就是对字符串"nuanyinni"进行操作,此时不要忘了,我们在进行递归的时候,还有str[end] = tmp,这一步其实就是在外边留了h,当我们不断重复前面过程的时候,每次将首元素留下,当str[0] = '\0’时递归结束,这时我们就要一层一层往出走,这个时候h是第一次调用reverse_string进行递归时留下的,所以也就是最外层的,即最后才出.同理,每一次进行递归调用都会留下一个字符作为尾字符,出的时候从内层逐渐到最外层,最终也就是完成了这个将字符串反向排序的过程.
完整代码如下:

#include <stdio.h>
#include <stdlib.h>
//编写一个函数reverse_string(char* string)(递归实现) 
int Strlen(char* str){	//定义函数求字符串长度
	int i;
	//当str[i] = '\0'时跳出循环,此时i就是字符串的长度
	for (i = 0; str[i]; ++i);
	return i;
}
void reverse_string(char* string){
	int end = Strlen(string) - 1;
	char tmp = string[0];
	if (string[0]){
		string[0] = string[end];
		string[end] = '\0';
		reverse_string(string + 1);
		string[end] = tmp;
	}
}
int main(){
	char str[] = "huanyinnin";
	reverse_string(str);
	printf("%s\n", str);
	system("pause");
	return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值