-字符串逆序排列(递归+嵌套)
一 问题描述:
编写一个函数 reverse_string(char* string)
实现:将参数字符串中的字符反向排列。
比如 :
char arr[] = “abcdef”;
逆序之后数组的内容变成:fedcba (不是逆序打印,而是改变数组内的顺序,整体输出数组里的字符串)
要求:使用递归和函数的嵌套(求字符串长度部分要求嵌套,且要求不能使用strlen函数)
二 思路分析
假设我们每次改变一个字母,可以考虑从前往后赋值,如下:
abcdef-- > fbcdef-- > fecdef-- > feddef-- > fedcef-- > fedcbf-- > fedcba
既然如此,那么也可以从后往前赋值,两者结合,也就是交换对称位置字符串的值,那么上述顺序可以变为:
abcdef-- > fecdea-- > fecdba-- > fedcba
考虑到这里,这个问题就可以利用循环实现,只需要进行字符串长度一半的循环次数便可实现。代码如下:
int my_strlen(char* p)
{
int n = 0;
while (*p != '\0')
{
p++;
n++;
}
return n;
}
void reverse_string(char* string)
{
int strlength = my_strlen(string);
for (int i = 0; i < (strlength/2); i++)
{
char temp = 0;
temp = *(string + i);
*(string + i) = *(string + strlength - 1 - i);
*(string + strlength -1- i) = temp;
}
}
int main()
{
char arr[] = "abcdef";
reverse_string(arr);
printf("%s", arr);
return 0;
}
如果用递归实现,考虑到每次递归所作的事情就是交换值,假设字符串长度为strlength,代码如下:
char temp = *string;
*string = *(string + strlength - 1);
*(string + strlength - 1) =temp;
那么此处如何设置回归的条件呢?
我们想到此处*(string + strlength - 1) =temp;
可以在函数回归后处理,那么我们就可以设置此处为'\0'
,每次递归后从后向前依次设置为'\0'
,至首位地址元素为'\0'
时,表明已把所有值交换完成。代码如下:
char temp = *string;
*string = *(string + strlength - 1);
*(string + strlength - 1) = '\0';
if (*(string + 1) != '\0')
{
reverse_string(string + 1);
}
*(string + strlength - 1) =temp;
至此,就可以实现了。
三 代码如下
int my_strlen(char* p)
{
int n = 0;
while (*p != '\0')
{
p++;
n++;
}
return n;
}
void reverse_string(char* string)
{
int strlength=my_strlen(string);
char temp = *string;
*string = *(string + strlength - 1);
*(string + strlength - 1) = '\0';
if (*(string + 1) != '\0')
{
reverse_string(string + 1);
}
*(string + strlength - 1) =temp;
}
int main()
{
char arr[] = "abcdef";
reverse_string(arr);
printf("%s", arr);
return 0;
}
运行结果如下:
四 其他思路下的代码
有兴趣的话,可以自行研究
方法一:非递归,改变循环的控制条件
int my_strlen(char* p)
{
int n = 0;
while (*p != '\0')
{
p++;
n++;
}
return n;
}
void reverse_string(char* string)
{
int strlength = my_strlen(string);
int l = 0;
int r = strlength - 1;
while (l < r)
{
char temp = 0;
temp = *(string + l);
*(string + l) = *(string + r);
*(string + r) = temp;
l++;
r--;
}
}
int main()
{
char arr[] = "abcdef";
reverse_string(arr);
printf("%s", arr);
return 0;
}
方法二:递归,改变递归的限制条件
int my_strlen(char* p)
{
int n = 0;
while (*p != '\0')
{
p++;
n++;
}
return n;
}
void reverse_string(char* string)
{
int strlength = my_strlen(string);
char temp = *string;
*string = *(string + strlength - 1);
*(string + strlength - 1) = '\0';
if (my_strlen(string+1)>=2)
{
reverse_string(string + 1);
}
*(string + strlength - 1) = temp;
}
int main()
{
char arr[] = "abcdef";
reverse_string(arr);
printf("%s", arr);
return 0;
}
方法三:递归,改变求strlength时的循环为递归
int my_strlen(char* p)
{
if(*p != '\0')
{
return 1 + my_strlen(p + 1);
}
else
{
return 0;
}
}
void reverse_string(char* string)
{
int strlength = my_strlen(string);
char temp = *string;
*string = *(string + strlength - 1);
*(string + strlength - 1) = '\0';
if (my_strlen(string+1)>=2)
{
reverse_string(string + 1);
}
*(string + strlength - 1) = temp;
}
int main()
{
char arr[] = "abcdef";
reverse_string(arr);
printf("%s", arr);
return 0;
}