单词翻转

GitHub跳转原题关系图返回列表

整行读入一次扫描:非空格字符进缓冲区,遇空格就把缓冲区逆序结算并原样保留空格,单遍 O(n)。

OJ: roj

题目 ID: 1144

难度:入门

标签:字符串python

创建: 2026-09-29 20:38

更新: 2026-10-05 03:27

题目描述

输入一个句子(一行,不超过 500 个字符),将句子中的每一个单词翻转后输出。单词之间以空格隔开,输出时单词之间的空格需与原文一致。

样例:输入 hello world,输出 olleh dlrow。

思路

空格是内容不是分隔符,必须整行读入:用一次扫描,非空格字符累积进缓冲区,遇到空格就把缓冲区逆序追加到结果、再原样补上这个空格,行尾对缓冲区做一次兜底结算。每个字符只被处理常数次,复杂度 O(n)O(n),连续空格、串首尾空格都由同一机制天然覆盖。

参考代码

Python 版:

python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-29 20:39
# update_at: 2026-10-04 14:36

import re
import sys


def reverse_words(line: str) -> str:
    r"""逐词反转:\S+ 只命中连续非空白段(单词),段外空白不参与匹配、原样保留。"""
    return re.sub(r"\S+", lambda seg: seg.group()[::-1], line)


def solve() -> None:
    data = iter(sys.stdin.read().splitlines())  # 一行一个元素,不切分 token
    line = next(data)  # 空格是内容不是分隔符:逐行产出才能整行拿到,行内空格原样保留
    print(reverse_words(line))


if __name__ == "__main__":
    solve()

C++ 版(同一算法):

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-10-05 03:27
 * update_at: 2026-10-05 03:27
 */

#include <cstdio>
#include <cstring>

typedef long long ll;

const int MAXN = 505;

char line[MAXN];   // 整行原文,空格是内容,必须保留
char ans[MAXN];    // 翻转后的结果串
char word[MAXN];   // 当前单词的缓冲区

int main() {
    // 空格是内容不是分隔符:用 fgets 整行读,保留行内空格
    if (fgets(line, MAXN, stdin) == NULL) {
        return 0;
    }
    // 去掉行末换行
    ll len = strlen(line);
    while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) {
        len--;
    }
    line[len] = '\0';

    // 扫描整行:非空格字符进缓冲区,遇到空格就反转结算,空格原样保留
    ll ans_len = 0;  // ans 的当前长度
    ll word_len = 0; // word 缓冲区当前长度
    for (ll i = 0; i < len; i++) {
        if (line[i] != ' ') {
            word[word_len++] = line[i]; // 累积单词字符
        } else {
            // 结算当前单词:逆序追加到结果
            for (ll j = word_len - 1; j >= 0; j--) {
                ans[ans_len++] = word[j];
            }
            word_len = 0;
            ans[ans_len++] = ' '; // 空格原样保留,连续空格也走这里
        }
    }
    // 行尾兜底:最后一个单词后面没有空格,单独结算
    for (ll j = word_len - 1; j >= 0; j--) {
        ans[ans_len++] = word[j];
    }
    ans[ans_len] = '\0';

    printf("%s\n", ans);
    return 0;
}