1. 题目描述:倒置字符串
牛客网OJ题链接
描述
将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I
输入描述:
每个测试输入包含1个测试用例: I like beijing. 输入用例长度不超过100
输出描述:
依次输出倒置之后的字符串,以空格分割
示例1
输入:
I like beijing.
输出:
beijing. like I
2. 思路
一开始的思路我想着再创建一个数组str2存放我们倒置的字符串,我尝试倒着遍历源数组str1 然后判断第一个空格的地方 将beijing赋值给str2,但是到第二个单词like ,我耗费了蛮多时间,都没办法确定它的结束地址,
因为对于beijing 我是从发现的第一个空格,一直遍历到str1字符串结尾,把这个整体赋值给str2,但是对于like 单词我只能确定它的起始位置,我没有办法确定它的结束位置。
之后在网上看了下才发现原来还有这样的巧妙思路:
先把整个字符串整体逆序,然后再将每个单词逆序
单词逆序的时候需要确定单词的起始位置和结束位置
start初值是我们的数组首元素地址
更新的时候我们判断是否是空格,空格-1位置就是我们第一个单词的结尾,空格+1就是下一个单词的起始位置
示例
3. 代码实现
#include <stdio.h>
#include<assert.h>void reserveStr(char* left, char* right) {assert(left && right);while (left < right) {char tem = *left;*left = *right;*right = tem;left++;right--;}
}int main() {char str[100] = { 0 };gets(str);int size = strlen(str);char* left = str;char* right = str + size - 1;reserveStr(left, right);char* cur = str;char* start = cur; //我们需要确定每个单词的起始位置start和结束位置cur// 这个start初始就是我们的数组首地址,start在循环中要随时更新,//我们每次走到空格的时候就记录了单词的结束位置就是cur-1//下一个单词就是空格+1的位置while (*cur != '\0') {if (*cur == ' ') {reserveStr(start, cur - 1);start = cur + 1;}cur++;if(*cur =='\0')//最开始我没有考虑到这个if,在牛客网验证的时候发现最后一个单词没有逆置//然后反应过来,最后一个单词的结尾是'\0',所以我们结尾单词需要另外考虑{reserveStr(start, cur - 1);}}printf("%s", str);return 0;
}
4.代码实现2
和1的思路类似,但是有些许不同
这个是判断如果不是空格或者不是’\0’,我们就cur++
#include <stdio.h>
#include <string.h>
#include <assert.h>void reverse(char* left, char* right) {assert(left && right);while (left < right) {char tmp = *left;*left = *right;*right = tmp;left++;right--;}
}int main() {char arr[100] = { 0 };//输入gets(arr);int len = strlen(arr);//完成这个逆序//1. 逆序整个字符串reverse(arr, arr + len - 1);//逆序每个单词char* cur = arr;while (*cur) {char* start = cur;while (*cur != ' ' && *cur != '\0') {cur++;}reverse(start, cur - 1);if (*cur != '\0')cur++;}//打印printf("%s\n", arr);return 0;
}