题目要求:在不利用字符串处理函数的情况下使用递归将字符串内容逆序。不是逆序打印!!
假定字符串为arr="abcdef";
第一步,我们需要分析如何将字符串逆序?
如上图所示,我们最容易想到的就是从两端开始进行互换操作;而通过指针进行操作是十分方便的
那么我就继续下一步
第二步,先使用非递归方式进行操作
int Strlen(char* str)//计算字符串长度的函数
{
int count = 0;
while (*str!= '\0')//指针解引用后不能为\0,也就是\0前所有的字符
{
count++;
str++; //指针右移
}
return count;
}
void revers(char* str)
{
int left = 0; //初始化左下表与右下标
int right = Strlen(str) - 1;
while (left < right) //当左下标与右下标重合时结束,两者之间已无元素要换
{
char tmp = *(str + left); //利用中间变量将两值进行交换
*(str + left) = *(str + right);
*(str + right) = tmp;
left++; //交换完成后,左下标右移,右下标左移,也就是向中间靠拢
right--;
}
}
int main()
{
char arr[] = "abcdef";
revers(arr); //将字符串首地址传入函数,通过地址可直接对数组进行操作
printf("%s", arr);
}
那么通过使用非递归方式解完,我们不难发现一个规律,这个规律就是左右下表的移动是固定的,
此时我们在考虑用递归的方法之前还有个小问题要解决,下图为问题引入
通过这张图我们可以看出,若是直接进行交换,就会导致我们求字符串长度时产生问题,而字符串长度的问题会带入下次运算,而右侧指针的位置始终处于\0前侧,这就会导致我们字符交换产生错误, 而解决的方式就是在进入下次递归之前将右侧值赋于\0,那么在计算字符串长度时就会计算左侧指针右移一位并且右侧指针左移一位后的长度,而在递归结束之后,再将本层变量tmp中的值赋予右侧。
#include<stdio.h>
int Strlen(char *str) //跟上一次一样,求字符串长度
{ //值得注意的是我们的判断结束的标志是\0
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
void reverse_string(char* str)
{
int len = Strlen(str);
char tmp = *str;
*str = *(str + len - 1);
*(str + len - 1) = '\0'; //在进入下次递归时,计算长度时右侧往左移一位
if (Strlen(str+1)>=2)
{
reverse_string(str+1); //进入下次递归时,左侧指针右移一位
}
*(str + len - 1) = tmp; //在递归结束时,将本层的tmp中保存的值赋给右侧
}
int main()
{
//字符串逆序(递归实现)
char arr[] = "abcdef";
reverse_string(arr);
printf("%s\n", arr);
return 0;
}
总结:通过上述解法,揭示了递归的方式其本质是将一个大型的工作转换成重复的小型工作,而我们在设计递归函数时,需要注意的一个很重要的点,就是变化量的控制,就像本题,如果对右侧指针指向的值过早进行交换赋值就会导致下一次运算的错误。
都看到这里啦,给个免费的赞吧,嘿嘿,谢谢啦!