前言:内容包括:题目,代码实现,大致思路,代码解读
题目:
链接:倒置字符串__牛客网
将一句话的单词进行倒置,标点不倒置。比如 "I like beijing.",经过处理后变为:"beijing. like I"。
字符串长度不超过100。
输入描述:
输入一个仅包含小写字母、空格、'.' 的字符串,长度不超过100。
'.' 只出现在最后一个单词的末尾。
输出描述:
依次输出倒置之后的字符串,以空格分割。
示例1
输入
I like beijing.
输出
beijing. like I
代码实现:
#include<stdio.h>
#include<string.h>
void reverse(char* left, char* right)
{
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char arr[101] = { 0 };
gets(arr);
int len = strlen(arr);
//1 逆序整个字符串
reverse(arr, arr + len - 1);
//2 逆序每个单词
char* str = arr;
while (*str)
{
char* start = str;
while (*str != ' ' && *str != '\0')
{
str++;
}
reverse(start, str - 1);
if (*str != '\0')
{
str++;
}
}
printf("%s", arr);
return 0;
}
大致思路:
1. 将整个字符串逆序
I like beijing. 逆序成:
.gnijieb ekil I
2. 将每个单词逆序
beijing like I
3 打印逆序后的字符串
代码解读:
函数部分:逆序字符串
void reverse(char* left, char* right)
{
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
得到指向字符串开头和末尾的指针left ,right,即可逆序字符串
一对一对的交换,且区间必须是有效区间,即left=right(仅有一个字符没必要交换)or left>right 都无需交换
主体部分
part 1:逆序整个字符串
char arr[101] = { 0 };
gets(arr);
int len = strlen(arr);
//1 逆序整个字符串
reverse(arr, arr + len - 1);
注意:读取包含空格的字符串不能使用scanf,可以使用gets,因为gets可以读取有空格的字符串
1. 求出输入的字符串的长度,用于找到此字符串末尾字符的下标:len-1
2. 将输入的字符串整个逆序,交由reverse函数实现,传递此字符串的起始地址arr,和最后一个字符的地址arr+len-1
part 2:逆序字符串中的每一个单词
char* str = arr;
while (*str)
{
char* start = str;
while (*str != ' ' && *str != '\0')
{
str++;
}
reverse(start, str - 1);
if (*str != '\0')
{
str++;
}
}
需要一个指针str去遍历整个字符串
需要一个指针start记录每个单词的起始地址
1 每一次循环的开始str都会指向一个单词的首字母,我们将这个地址存入start指针中
2 有了一个单词的起始地址后,我们需要达到逆序每个单词的效果,故而我们需要让str指针指向一个单词的结束标志:空格(不是最后一个单词的结束标志)or '\0'(最后一个单词的结束标志)
若是*str的内容不是空格并且不是'\0',则str++,不断跳过一个单词的每个字符,直至跳完整个单词,指向空格 or '\0'
3 这时一个单词我们已经跳完了,需要使用reverse函数逆序这个单词,传递这个单词的起始地址start,和末尾地址str-1
4 逆序完一个单词后判断此单词是否为最后一个单词,若不是最后一个单词则str++,指向下一个单词的起始地址,若是最后一个单词则str无需++,while循环结束
但是:若是最后一个单词也逆序好了,str就不需要再继续++,指向下一个字符了
故而我们在逆序完一个单词后使用str++指向下一个单词的起始地址之前,需要判断,这个被逆序的单词是不是最后一个单词,最后一个单词的标志是:它的末尾是'\0'