逆序字符串的两种思路(得出思路之前,要先分析,只有分析才能得出思路):
分析:逆序字符串这个问题用画图来解决
原先数组里面存放的是“abcde",现在题目让我们存放”edcba",也就是a的位置现在放了e这个值,e的位置现在放了a的值,以此类推,也就是两个值进行了交换,也就是两个房间的东西进行交换。所以这时候思路就出来了,通过访问下标或者地址找到元素里的值,再进行交换即可,这里有好几组需要交换,所以需要使用循环语句来实现。
第一种思路出来之后,再想递归算法就会简单很多啦。
使用递归算法之前,要先创建函数,函数的功能是逆序字符串abcde,通过想第一种思路,可以把逆序abcdef转化为:先交换a和e,再加上逆序bcd,逆序bcd可以转化为:先交换b和d,此时发现传进来的字符串只有一个字符,不需要再进行交换了。
第一种思路:第一步:找到一前一后两个字符,第二步:进行交换
第二种思路:使用递归算法,第一步:找到最左和最右的两个元素,第二步:进行交换,第三步:剩余的字符串交给自己的函数。
找到字符的方法有两种,一种是由于字符串放到了数组中,通过访问下标定位元素,另一种通过地址定位元素。
第一种:
通过访问下标定位元素
#include<stdio.h>
#include<string.h>
//通过下标找到元素
//实现函数
void reverse(char* arr)
{
// 找到元素对应的下标
int left = 0;
int right = strlen(arr) - 1;
// 进行交换值
int i = 0;
int avg = (left + right) / 2;
for (i = 0;i < avg;i++)
{
int tmp = 0;
tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
int main()
{
char arr[] = "abcdefg";
// 创建函数实现逆置功能
reverse(arr);
// 打印数组
printf("%s", arr);
return 0;
}
通过地址定位元素
#include<stdio.h>
#include<string.h>
// 通过地址找到元素
//实现函数
void reverse(char* arr,int str )
{
// 通过地址,找到元素
char* left = arr;
char* right = arr + str - 1;
// 交换
int avg = str / 2;
int i = 0;
for (i = 0;i < avg;i++)
{
char tmp = 0;
tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char arr[] = "abcdefg";
int str = strlen(arr);
//创建函数,实现逆置功能
reverse(arr,str);
//打印数组
printf("%s", arr);
return 0;
}
第二种:
通过访问下标定位元素
#include<stdio.h>
#include<string.h>
// 实现函数
void reverse(char* arr)
{
// 找到左右字符,完成交换
// 由于每次传进来的字符串是新的字符串,所以每次都要重新确定下标
int left = 0;
int right = strlen(arr)-1;
char tmp = 0;
tmp = arr[left];
arr[left] = arr[right];
arr[right] = '\0';
// 调用自己函数,完成剩下字符的交换
if (*(arr + 1) != '\0')
{
reverse(arr + 1);
}
arr[right] = tmp;
}
int main()
{
char arr[] = "abcdefg";
//创建函数
reverse(arr);
//打印函数
printf("%s", arr);
return 0;
}
通过地址找到元素
#include<stdio.h>
#include<string.h>
//实现函数
void reverse(char* arr)
{
// 通过地址找到左右下标,并进行交换
char tmp = *arr;
int len = strlen(arr);
*arr = *(arr + len - 1);
*(arr + len - 1) = '\0';
// 调用自身函数,完成中间字符串的逆置
if (*(arr + 1) != '\0')
{
reverse(arr + 1);
}
*(arr+len-1) = tmp;
}
int main()
{
char arr[] = "abcdefg";
//创建函数
reverse(arr);
//在控制台打印逆置好的数组
printf("%s", arr);
return 0;
}
使用递归算法时的 注意事项:
一:通过下标找到最左和最右的字符时,在每次调用自己的函数时,传给函数的字符串每次都会改变,长度会改变,所以最右边的下标会改变,要考虑好,最左边的下标起始都是0,不要去动它。
二:通过地址,找到字符,进行交换时,要真正对数组里的元素进行操作,而不是对值进行拷贝,拷贝到一个变量,对变量进行操作,操作的对象不要搞错。拷贝的话,仅仅对拷贝的值,也就是对分身进行了操作,而真身纹丝不动。
下面是对第二个注意事项的错误做法:
#include<stdio.h>
#include<string.h>
//实现函数
void reverse(char* arr)
{
// 通过地址找到左右下标,并进行交换
char left = *arr;
int len = strlen(arr);
char right = *(arr + len - 1);
char tmp = left;
left = right;
right = '\0';
// 调用自身函数,完成中间字符串的逆置
if (*(arr + 1) != '\0')
{
reverse(arr + 1);
}
right = tmp;
}
int main()
{
char arr[] = "abcdefg";
//创建函数
reverse(arr);
//在控制台打印逆置好的数组
printf("%s", arr);
return 0;
}
可以看到,数组并没有逆置。
在代码里,创建了left和right变量,将值拷贝到了这两个变量里面,只是对变量进行了操作,也就是只是对拷贝过来的值进行了操作,并没有对真身造成真正的操作。