开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情
前言
本文是关于刷题——倒置字符串单词的C语言实现。
新手一个,水平比较低,还请包涵。
题目描述
【倒置字符串】
将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I
输入描述:每个测试输入包含1个测试用例: I like beijing. 输入用例长度不超过100
输出描述:依次输出倒置之后的字符串,以空格分割
示例:
输入
I like beijing.
输出
beijing. like I
注意
要认真审题,这可不是逆序字符串的每个字符,而是以单词为单位(包括标点符号,不过该题标点符号只考虑句末的点号 . ),让单词的顺序逆序。
递归分割法
如何分割
既然要以单词为单位逆序,那么我们就先考虑一下把单词分割出来,怎么分呢?
想想看,输入的字符串中每个单词之间是不是都以空格' '为间隔,以此来区别不同的单词,我们可不可以利用这一点来分割单词呢?
而我们又知道:C语言里用'\0'来标示字符串的结束,那我们可以不可以把输入的字符串中的空格给换成'\0' 呢?这样一来原字符串就被分割成了若干个小的字符串,每一个小的字符串就是一个单词(包括标点符号),当我们要读取单个单词的时候只要知到单词头部的地址就可以了呗。
我们用一个指针来标识单词的头部,让指针不断向后偏移,直到遇上空格或'\0'才停下,要是遇上空格的话,就把空格给换成'\0',然后从下一个字符处继续偏移重复上述过程。
图解
对应代码
void ReverseStr(char* str)
{
//遇到空格说明到达单词末尾了
//而遇到'\0'说明到达原字符串末尾了
while((*str != ' ') && (*str != '\0'))
{
str++;
}
//单词末尾处,分割单词
if(*str == ' ')
{
//把空格换成'\0'
*str = '\0';
//把指针向后偏移一个单位后递归
ReverseStr(str + 1);
}
}
如何逆序打印
逆序什么的用递归省事多了,前面不是一直让指针向后偏移再递归嘛,正好偏移到原字符串末尾处时停下来,此时*str值为'\0',不符和if(*str == ' ')条件,也就不再递归下去了,那就开始打印。
你可能会疑惑:你这样都让指针偏移到字符串末尾了还咋一个一个打印单词啊?
别着急,我们只需要在每次进入函数时拷贝一份指针的值不就行了吗。
况且每次分割完一个单词后才递归再次进入函数。
不递归后开始打印字符串,因为是向后偏移递归,所以最先打印的就是最后的单词。
图解
对应代码
void ReverseStr(char* str)
{
char* str_cy = str;
while((*str != ' ') && (*str != '\0'))
{
str++;
}
if(*str == ' ')
{
*str = '\0';
ReverseStr(str + 1);
}
printf("%s ", str_cy);
}
完整代码
#include<stdio.h>
void ReverseStr(char* str)
{
char* str_cy = str;
while((*str != ' ') && (*str != '\0'))
{
str++;
}
if(*str == ' ')
{
*str = '\0';
ReverseStr(str + 1);
}
printf("%s ", str_cy);
}
int main()
{
char str[101] = {0};
gets(str);
ReverseStr(str);
return 0;
}
双重翻转法
思路
先将整个字符串翻转逆序,再一个一个单词翻转逆序。
实现代码
void ReverseStr(char *left, char *right)
{
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char str[1001] = {0};
gets(str);
char* left = str;
int len = strlen(str);
char* right = str + len - 1;
ReverseStr(left, right);//整个字符串逆序翻转
char* start = str;
char* end = start;
while (*start)//双指针偏移定位单词头尾位置以区分单词并逆序翻转
{
//用end找到单词末尾处(end-1)
while (*end != ' ' && *end != '\0')
{
end++;
}
//逆序翻转一下单个单词
ReverseStr(start, end - 1);
//空格说明不是最后一个单词
if (*end == ' ')
end++;
start = end;
}
printf("%s", str);
return 0;
}