前言
大家好,我是熊猫,今天要和大家一起学习的是牛客网上一道编程题----倒置字符串,本题解法多样,熊猫今天整理了三种不同的解法,希望可以给大家提供不同的解题思想。
一、题目描述
将一句话的单词进行倒置,标点不倒置。比如 “I like beijing.”,经过处理后变为:“beijing. like I”。
字符串长度不超过100。输入描述:
输入一个仅包含小写字母、空格、‘.’ 的字符串,长度不超过100。
‘.’ 只出现在最后一个单词的末尾。输出描述:
依次输出倒置之后的字符串,以空格分割。
二、题目解析
(一)解法1
首先我们一起来分析分析这道题,‘将一句话的单词进行倒置,标点不倒置’,那么我们首先想到的可能就是从后往前将单词逆序拿出来,这种方法当然是行得通的,那我们就需要创建一个新的数组来存放取出来的单词,同时大家需要注意最后的‘.’不要忘记了。
下面函数中调用了一个assert函数,我们需要在前方引用头文件<assert.h>
它的用途是判断条件是否为真,在debug环境下可以当做 if语句来看待
代码如下(示例):
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<assert.h>
char* inv(const char str[], char arr[], const int sz) {
assert(str && arr);//断言(判断)
int right = sz - 1;
int left = right;
int i = 0;
for (; right >= 0; right--) {
if (str[right] == ' ' || right == 0) {
//单词与单词之间都有空格间隔,遇到空格就讲它之后的单词复制到arr数组中
if (right == 0)
left = 0;
else
left = right + 1;
do {
arr[i++] = str[left++];//这样可以直接将空格也同时录入
if (str[left] == '\0')
arr[i++] = ' ';
} while (isalpha(arr[i - 1]));//<ctype.h>中的函数,该字符是字母返回1,否则返回0
}
}
arr[i] = '\0';
return arr;
}
int main() {
char str[101] = { 0 };//字符串长度不超过100,最后还有一个'\0'
gets(str);//由于scanf遇到空格或者换行会停止读取数据,所以这里使用gets(读取字符串)
char arr[101] = { 0 };
int sz = strlen(str);//求字符串长度,不包括'\0'
printf("%s\n", inv(str, arr, sz));
return 0;
}
(二)解法2
这里我们来认识一种很巧妙的方法,先将每个单词进行逆序,之后再将整个字符串进行逆序,这种方法还有一个优点就是:不用考虑空格与’\0’。
代码如下(示例):
void reverse(char str[], int left, int right) {
assert(str);
while (left <= right) {
char ch = str[left];
str[left] = str[right];
str[right] = ch;
left++;
right--;
}
}
int main() {
char str[101] = { 0 };
gets(str);
int sz = strlen(str);
int i = 0;//用来记录单词最后一个字母的下标(最后的句号也算在单词里)
int j = 0;//用来记录单词第一个字母的下标
for (i = 0; i <= sz; i++) {
if (str[i] == ' ' || str[i] == '\0') {
reverse(str, j, i - 1);//每个单词进行倒置
j = i + 1;
}
}
reverse(str, 0, sz - 1);//整个句子进行倒置
printf("%s\n", str);
return 0;
}
(三)解法3
下面我们介绍一种“偷鸡”取巧的方法,通过递归,将每一个单词存在一个字符串中,倒序输出。
代码如下(示例):
void fun() {
char str[101] = { 0 };
if (scanf("%s", &str) != EOF) {//EOF一般是-1,当数据读取失败时会返回EOF,自行测试的时候按“Ctrl+z”结束
fun();
printf("%s ", str);//scanf遇到空格就停止读取,所以空格需要我们自行输出
}
}
int main() {
fun();
return 0;
}
总结
以上就是熊猫对这个题目的理解,顺带一提:题解一的适用范围很小,甚至可以说只使用与题目这种情况,如果再增加其他字符那就很可能得不到我们想要的结果,而如果递归使用的不是那么精通的话,题解三是很难想到的,所以大家做题时尽可能地使用解法二。
如果大家还有其他好的做法欢迎在评论区留言,大家的点赞与收藏不断更新的动力,感谢大家的支持。