易中 · 字符串

反转单词顺序

cin >> x 只读一个单词,碰到空格就停。句子需要别的工具 —— 拿到整行之后,拆单词不过是一个带着两个下标的循环。

一句话答案用 <code>cin.getline</code> 读入整行,按空格切成单词存起来,然后从最后一个词往回打印,单词间单个空格。

题目

输入: 一行文本:1 到 100 个单词,单词之间一个或多个空格。单词本身不含空格;整行不超过 200 个字符。

输出: 同样的单词按相反顺序输出,单词之间单个空格,最后换行。

样例:

输入输出
the quick brown foxfox brown quick the
hellohello
a b cc b a

翻转的是单词的顺序,每个单词内部的字母不动 —— 反转的是「单词序列」,不是单词里的字符(那是 反转字符串)。

你的解答

main.cpp — 你的解答
「运行我的输入」用的自定义输入

判题在浏览器本地运行。死循环会在 3 秒后被自动中断 —— 但还是确保每个循环都有出口。代码随打随存。

卡住了?提示

提示 1 — 你要的是整行,不是单个词

cin >> word 碰到空格就停,所以对 the quick brown fox 你只会拿到 the。cin.getline(line, 205) 会一直读到换行符 —— 空格也照收,句子要的就是这个。

提示 2 — 两个下标走一遍整行

用一个下标 i 向后扫。停在字母上时,用第二个下标记住这个单词的起点,一路抄到空格或 '\0'。这一对起止就是一个单词。把每个词存进二维 char 数组,比如 char words[50][105] —— 第 k 行就是第 k 个单词。

提示 3 — 倒着打印那些行

如果存了 count 个单词,最后一个在第 count - 1 行。从 count - 1 倒数到 0 的 for 就是倒序输出;单词之间打一个空格,最后一个后面别打。输入里连续多个空格在输出里合成一个 —— 没关系,判题只看单词序列。

题解(先自己试试!)
#include <iostream>
#include <cstring>
using namespace std;

int main() {
    char line[205];
    cin.getline(line, 205);

    char words[50][105];
    int count = 0;
    int i = 0;
    while (line[i] != '\0') {
        while (line[i] == ' ') i++;
        if (line[i] == '\0') break;
        int j = 0;
        while (line[i] != '\0' && line[i] != ' ') {
            words[count][j] = line[i];
            i++;
            j++;
        }
        words[count][j] = '\0';
        count++;
    }

    for (int k = count - 1; k >= 0; k--) {
        cout << words[k];
        if (k > 0) cout << " ";
    }
    cout << endl;
    return 0;
}

这个「拆开再存」的循环,和 数单词 用来计数的是同一套机器 —— 差别只是一个动作。加练:打印的同时把单词数也算出来,在第二行输出。字符串这条线的下一站,是两头同时往中间走的 回文串。

深度解析

为什么这样做对

一个句子不是一个词 —— 它是词的序列。套路是「扫、切、存」:一个下标走整行,第二个下标切出每个词,存进数组 —— 从此这些词随你按什么顺序取用。先拆再处理会在所有文本任务里反复出现,从数单词到解析 CSV。

代价

切一遍加打印一遍:行长 L 时是 O(L) 时间,存词需要 O(L) 额外空间。L ≤ 200 时微不足道 —— 同样的代码撑得起十万字符的行。

常见错法

  • 用 cin >> s 而不是 cin.getline —— 你只会拿到一个词,所有多词的测试全挂,而且不注意到空格丢了就发现不了。
  • 把词抄进行里之后忘了补 '\0'。没有终止符,cout << words[k] 会接着把内存里后面的东西一起打出来。

下一步

同一个「边扫边切」的循环,把「存起来」换成「计数」就是 数单词 —— 对切出来的东西换个动作,就是一道新题。

记住这两句

  • cin >> 读一个词;cin.getline 读整行 —— 按输入长什么样来选,别按习惯。
  • 反转单词 = 全部存下来,再倒着打印那些行。
🐞 这段是错的 —— 点开,亲手让它挂一次

原样照抄整行 —— 单词动都没动

#include <iostream>
using namespace std;

int main() {
    char line[205];
    cin.getline(line, 205);
    cout << line << endl;
    return 0;
}