【GESP】C++三级练习 luogu-B3640 T3 句子反转
GESP三级练习,字符串转换相关,与以往真题难度相当,难度★★☆☆☆。
luogu-B3640 T3 句子反转
题目要求
题目描述
给定一行句子,每个词之间用空格隔开,要么是全小写英文单词,要么是全大写英文单词,要么是自然数。
要求将这些单词倒序输出。而且对于每个单词,如果是小写词,应当转为大写;如果是大写词,应当转为小写;如果是自然数,应该倒转输出。
举一个例子:
1 we choose TO go 2 the 123 moon程序应当输出:
1 MOON 321 THE 2 GO to CHOOSE WE
输入格式
仅一行,即需要反转的句子。
输出格式
仅一行,表示程序对句子的处理结果。
输入输出样例 #1
输入 #1
1
we choose TO go 2 the 123 moon
输出 #1
1
MOON 321 THE 2 GO to CHOOSE WE
说明/提示
样例解释
首先应当按单词逆序,即:
1
moon 123 the 2 go TO choose we
小写变大写、大写变小写、倒转自然数之后,得到最终结果:
1
MOON 321 THE 2 GO to CHOOSE WE
数据规模与约定
对于 $100\%$ 的数据,句子中包含的单词数量不超过 $1000$,每个单词长度不超过 $6$。
题目分析
解题思路
本题的解题思路如下:
- 问题分析:
- 需要将一行句子中的单词倒序输出
- 对于小写单词需要转为大写
- 对于大写单词需要转为小写
- 对于数字需要倒序输出
- 核心逻辑:
- 读取整行句子,按空格分割成单词
- 对每个单词进行判断和处理:
- 判断是小写单词、大写单词还是数字
- 根据类型进行相应转换
- 将处理后的单词按倒序拼接输出
- 实现要点:
- 字符串处理:
- 方法一:手动处理字符串
- 使用string类型存储单词
- 通过字符ASCII码判断大小写:
str[0] >= 'a' && str[0] <= 'z'
判断小写,str[0] >= 'A' && str[0] <= 'Z'
判断大写 - 通过ASCII码偏移量进行大小写转换:
str[i] - 'a' + 'A'
转大写,str[i] - 'A' + 'a'
转小写 - 通过字符串拼接实现数字倒序:
result = str[i] + result
- 方法二:使用内置函数
- 使用string类型存储单词
- 使用
islower()
和isupper()
判断字母大小写 - 使用
transform()
配合toupper()
和tolower()
进行大小写转换 - 使用
reverse()
函数处理数字倒序
- 方法一:手动处理字符串
- 单词存储和倒序:
- 可以直接在结果字符串前添加处理后的单词
- 也可以先存储到数组或vector中再倒序输出
- 注意题目给出的数据范围:
- 单词数量不超过1000
- 每个单词长度不超过6
- 字符串处理:
复杂度分析:
- 时间复杂度:$O(n)$,其中n为所有单词的总字符数
- 空间复杂度:$O(n)$,需要存储原始输入和处理后的结果
方法一:直接手搓大小写判断和转换
方法一示例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <string>
int main() {
// 用于存储当前读入的单词
std::string str;
// 用于存储最终结果
std::string result;
// 循环读取输入的单词,直到输入结束
while(std::cin >> str) {
// 如果是小写字母开头的单词
if (str[0] >= 'a' && str[0] <= 'z') {
// 将小写字母转换为大写字母
for (int i = 0; i < str.length(); i++) {
str[i] = str[i] - 'a' + 'A';
}
// 将转换后的单词添加到结果字符串的前面
result = str + result;
}
// 如果是大写字母开头的单词
else if (str[0] >= 'A' && str[0] <= 'Z') {
// 将大写字母转换为小写字母
for (int i = 0; i < str.length(); i++) {
str[i] = str[i] - 'A' + 'a';
}
// 将转换后的单词添加到结果字符串的前面
result = str + result;
}
// 如果是数字开头的单词
else if (str[0] >= '0' && str[0] <= '9') {
// 将数字字符串反转
for (int i = 0; i < str.length(); i++) {
result = str[i] + result;
}
}
// 在每个单词前添加空格
result = " " + result;
}
// 输出结果,去掉第一个空格
std::cout << result.substr(1) << std::endl;
return 0;
}
方法二:利用内置函数处理大小写转换和反转
方法二示例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <string>
#include <algorithm>
int main() {
// 用于存储当前读入的单词
std::string str;
// 用于存储最终结果字符串
std::string result;
// 循环读取输入的单词,直到输入结束
while(std::cin >> str) {
// 如果是小写字母开头的单词,将整个单词转换为大写
if (islower(str[0])) {
transform(str.begin(), str.end(), str.begin(), ::toupper);
}
// 如果是大写字母开头的单词,将整个单词转换为小写
else if (isupper(str[0])) {
transform(str.begin(), str.end(), str.begin(), ::tolower);
}
// 如果是数字,将数字字符串反转
else {
reverse(str.begin(), str.end());
}
// 将处理后的单词添加到结果字符串的前面
result = str + result;
// 在每个单词前添加空格
result = " " + result;
}
// 输出结果,去掉第一个空格
std::cout << result.substr(1) << std::endl;
return 0;
}
所有代码已上传至Github:https://github.com/lihongzheshuai/yummy-code
GESP各级别考纲要点、知识拓展和练习题目清单详见C++学习项目主页
“luogu-”系列题目已加入洛谷Java、C++初学团队,作业清单,可在线评测,团队名额有限,欢迎加入。
“bcqm-”系列题目可在编程启蒙题库进行在线评测。
本文由作者按照 CC BY 4.0 进行授权