top1编程
← 返回题目
题解

字符串反转

1 条题解

  • 0
    @ 2026-8-5 10:29:40

    解题思路

    小C喜欢把单词倒着写,我们要帮忙把每个单词"正过来"。注意:是每个单词分别反转,单词之间的顺序不能变。比如 "olleh !dlrow" 要变成 "hello world!":其中 "olleh" 反转为 "hello","!dlrow" 反转为 "world!"。

    这里有个小细节:"!" 和 "dlrow" 是紧紧挨在一起的,所以反转的时候要连在一起反转,就像它们是一个整体——也就是说,标点符号跟着它前面的字母一起反转。

    做法:

    1. 用 getline 读入一整行文本。
    2. 从头到尾扫描这一行,找到每一段"连续的非空格字符",这就是一个单词(标点符号也算在单词里)。
    3. 把这一段反转:用两个下标 l 和 r,一个指这一段的开头、一个指结尾,把这两个位置的字符交换,然后 l 往右走一格、r 往左走一格,继续交换,直到 l 和 r 碰头(或者 l 超过了 r)。
    4. 空格原样保留,单词之间的顺序不变。

    因为输入有多组样例,所以要循环处理 T 次。特别提醒一个坑:读入 T 之后,要先用 getline 把 T 后面的那个换行符"吃掉",否则第一行文本会被当成空行读进去。

    参考代码

    // 字符串反转:把每一行文本中的每个单词分别反转,单词顺序不变
    #include <iostream>
    #include <string>
    using namespace std;
    int main(){
        int T;
        cin>>T;
        string line;
        getline(cin,line);      // 吃掉T后面那一行的换行符
        while(T--){
            getline(cin,line);  // 整行读入一句话
            for(int i=0;i<line.size();){
                if(line[i]==' '){ i++; continue; } // 空格不用管
                int j=i;
                while(j<line.size()&&line[j]!=' ') j++; // j走到单词后的空格
                // 把这个单词([i,j)这一段)首尾交换实现反转
                for(int l=i,r=j-1;l<r;l++,r--) swap(line[l],line[r]);
                i=j; // 从下一个位置继续找单词
            }
            cout<<line<<'\n';
        }
        return 0;
    }
    

    复杂度分析

    • 时间复杂度:O(总字符数)。每个字符最多被交换一次。T 组样例一共读入多少个字符,就做多少次操作,所以总时间正比于总字符数。
    • 空间复杂度:O(L),L 是一行最多1000个字符,我们只需要同时存一行文本。
    • 1