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;
}