文章

【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$。


题目分析

解题思路

本题的解题思路如下:

  1. 问题分析:
    • 需要将一行句子中的单词倒序输出
    • 对于小写单词需要转为大写
    • 对于大写单词需要转为小写
    • 对于数字需要倒序输出
  2. 核心逻辑:
    • 读取整行句子,按空格分割成单词
    • 对每个单词进行判断和处理:
      • 判断是小写单词、大写单词还是数字
      • 根据类型进行相应转换
    • 将处理后的单词按倒序拼接输出
  3. 实现要点:
    • 字符串处理:
      • 方法一:手动处理字符串
        • 使用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 进行授权