目录
一.问题描述
一.问题分析
1.循环方式
2.递归方式
一.问题描述
请将字符串逆向排列,如将“abcdef”改变为“fedcba”。
二.问题分析
1.循环方式
循环的思路是重复执行,如何通过重复执行使得字符串倒序呢?
要使的字符串倒序,无非让这个字符串首尾两个字符互换,然后再让第二个和倒数第二个字符互换,接着再让第三个和倒数第三个字符互换,这样循环下去,最终换到没得换位置,那么这个字符串就完全倒序了
用代码实现这个过程:有上述分析不难想到设置多次循环,每次循环分别交换一次,不断往字符串中部挤,挤到没得换为止即可。
那么怎么交换两个字符呢?
arr[0] = arr[5];
arr[5] = arr[0];
我们不能写成上述代码,由于代码从上往下执行,那么arr[0]首先被成arr[6]的值,而arr[6]又被赋成arr[0],此时arr[0]里面已经装了arr[6]的值因此arr[6]相当于没换。若要交换则需设置一个临时变量:
int tmp = arr[0];
arr[0] = arr[5];
arr[5] = tmp;
相当于 要交换一瓶水和一瓶酱油,则需另外找一个空瓶子做中间交换媒介:
因此我们写出代码
int main()
{
char arr[10] = "abcdef";
int left = 0;
int right = strlen(arr) - 1;//下标访问,要减1。
while (left <= right)
{
int tmp = 0;
tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
printf("%s", arr);
return 0;
}
1.让left不断右移,让right不断左移,left和right放入arr[ ]中,使它们能充当下标访问数组元素 .
2.当left<right时,中间还有的换,当left=right时,刚好重合交换自己,当left>right时中间已经没有得换,跳出循环.
2.递归方式
递归的是大事化小,如何通过递归把问题重重简化呢?
假如f()是一个倒序函数,那么简化问题的思路应该是这样的
f(abcdef)——>操作a和f 再f(bcde)——>操作b和e再f(cd)——>操作c和d——>逐层返回。
那么如何设计这个函数呢?
先了解函数读取字符串的原则 :
假如函数f(char arr[])要读取字符串数组arr[]=“abcdef”
传参传的是数组名,而数组名是该数组首元素地址,由于数组在内存中是连续存放的,函数通过首元素地址可以找到这个数组的地址,然后一直往下读取,直到碰到\0(\0是字符串结束的标志)停止。设置的每个字符串默认最后带一个\0,只不过它不可见。即“abcdef\0”
首先,第一次传进去的是abcdef,而第二次传入的是bcde。当传入abcdef后我们要完成交换,但是若第一次出来直接变成fbcdea,那第二次怎么保证传入的是bcde呢?因此我们不能一步到位,需要一点过渡。
因为后面bcde后面总要有个字符,换之前是f,换了后是a。要使得传入的是bcde,必须改动这个字符串的最后一个字符,使其成为\0,我们都知道\0是字符串结束的标志,让函数读到c就结束,再让首元素地址往后推一个单位,把这个字符串的第一个字符跳过,这样就夹出了bcde。这样,我们就可以先把a换成f,(因为a换成什么对后面的运算已经不造成影响了)f先临时换成\0,最后再把\0换成a
a——>f , f——>\0——>a
因此,第一次递归:第一步:把a换成f
第二步:把f换成\0
第三步:再次调用函数,传入数组名+1
第四步:把\0换成f
由于递归需要限制条件,当我们传入的字符串数组长度小于2时,就没必要再传进去交换了,已经没得换了。
我们再用下标访问数组,则:
#include <string.h>
void upsidedown_exchange(char arr[])
{
char tmp = arr[0];//创建临时变量用于交换
int len = strlen(arr);//strlen 计算字符串长度
arr[0] = arr[len - 1] ;//len-1的减1是把首元素减掉,这样首元素的地址加上len-1才能刚好等于这个数组中最后一个元素
arr[len - 1] = '\0';
if (strlen(arr + 1) >= 2)//递归的限制条件
upsidedown_exchange(arr + 1);
arr[len - 1] = tmp;//最终实现交换
}
int main()
{
char arr[] = "abcdef";
upsidedown_exchange(arr);
printf("%s", arr);
return 0;
}
这样我们通过递归实现了字符串的倒序。