案例分析
例如,现在我们输入:"I like programming.",要求的输出是:"programming. like I"。
很显然与一般的逆序字符串是有区别的。但是这种区别是有联系的,现在我来分析一下思路。
1.如果我们先逆序字符串会发生什么?字符串逆序的代码是?
当我们编写一个独立函数来逆序字符串,那么输出的应该是:".gnimmargorp ekil I"。到这里不难发现我们只要再将特定的单词再次逆序,就能得到标准输出。
这是一个很好的思路。
好了,现在关心的问题是如何实现字符串逆序。
#include <string.h>
void reverse(char* left,char* right)
{
//逆序的本质就是头尾交换,所以我习惯定义成左右两个元素交换
while (left < right)
{
//交换过程
char tmp = *right;
*right = *left;
*left = tmp;
left++;
right--;
}
}
int main()
{
//创建存储字符串的数组
char arr[101] = { 0 };
//输入
gets(arr);
//逆序字符串
int len = strlen(arr);
reverse(arr, arr + len - 1);//我们将字符串首元素和尾元素地址作为参数
//打印
printf("%s\n", arr);
return 0;
}
运行的效果就是这样:
2.如何实现单词逆序?
我们需要两个指针,用来指向单词头和尾。
但是这样存在一个很大的弊端,那就是我们很难去找到任意一个单词的尾。那我们可以这样做:我们让"end"指针从头开始,往后遍历,直到碰到空格,我们就停止。
当这个过程完成之后,我们需要重置一下头指针(下一个单词的逆序)。不难看出,当"end"指针"++"一下,就可以指向"ekil"的首元素地址,那我们直接将此时"end"的地址赋给"start"指针就好啦。
重复这个步骤,不难发现我们可以用循环来控制需要逆序的次数,判断条件理所应当就是" *start != "\0" "。
那么代码我们就可以这样写:
#include <string.h>
void reverse(char* left,char* right)
{
//逆序的本质就是头尾交换,所以我习惯定义成左右两个元素交换
while (left < right)
{
//交换过程
char tmp = *right;
*right = *left;
*left = tmp;
left++;
right--;
}
}
int main()
{
//创建存储字符串的数组
char arr[101] = { 0 };
//输入
gets(arr);
//逆序字符串
int len = strlen(arr);
reverse(arr, arr + len - 1);//我们将字符串首元素和尾元素地址作为参数
//创建一个单词头指针
char* start=arr;
//单词逆序
while (*start)
{
//创建一个单词尾指针
char* end = start;
while (*end != ' ' && *end != '\0')
{
end++;
}
//逆序,此时end是指向空格的,所以需要-1
reverse(start, end - 1);
//重置头指针
end++;
start = end;
}
//打印
printf("%s\n", arr);
return 0;
}
到这里,我们的代码就写完了: