易中 · 字符串
反转单词顺序
cin >> x 只读一个单词,碰到空格就停。句子需要别的工具 —— 拿到整行之后,拆单词不过是一个带着两个下标的循环。
一句话答案用 <code>cin.getline</code> 读入整行,按空格切成单词存起来,然后从最后一个词往回打印,单词间单个空格。
题目
输入: 一行文本:1 到 100 个单词,单词之间一个或多个空格。单词本身不含空格;整行不超过 200 个字符。
输出: 同样的单词按相反顺序输出,单词之间单个空格,最后换行。
样例:
| 输入 | 输出 |
|---|---|
the quick brown fox | fox brown quick the |
hello | hello |
a b c | c b a |
翻转的是单词的顺序,每个单词内部的字母不动 —— 反转的是「单词序列」,不是单词里的字符(那是 反转字符串)。
你的解答
「运行我的输入」用的自定义输入
判题在浏览器本地运行。死循环会在 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;
}