字符串p型编码

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

把数字串切成极大同字符段,每段输出长度加字符,线性扫描即可完成。

OJ: roj

题目 ID: 1145

难度:入门

标签:入门字符串游程编码groupbypython

创建: 2026-09-29 21:04

更新: 2026-10-05 03:27

题目描述

给定一个只含数字字符的字符串 ss(长度不超过 10001000),把它切成每个极大同字符段。对每一段依次输出「段长 + 段字符」即可得到 ss 的 p 型编码串。例如 122344111 的切分为 1, 22, 3, 44, 111,编码结果为 1122132431。

思路

维护当前段起点,从左向右扫描字符串,当遇到下一个字符不同或到达串尾时结算当前段,输出段长与段字符即可。段长需要用十进制完整输出(如 00000000000 输出 110)。

参考代码

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 21:20
# update_at: 2026-09-29 21:20

import sys
from itertools import groupby


def encode(text: str) -> str:
    """把原串压成 p 型编码串:每个连续段输出「段长 + 该数字」。

    题目例子 122344111 → 1个1、2个2、1个3、2个4、3个1 → 1122132431,
    也就是对每个极大同字符段依次写出 len(段) 与段字符。
    """
    return "".join(f"{len(list(run))}{digit}" for digit, run in groupby(text))


def solve() -> None:
    text = sys.stdin.read().strip()   # 整行即整串,题面保证串内没有空白字符
    print(encode(text))


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 <iostream>
#include <string>
using namespace std;

typedef long long ll;

string s; // 输入的数字字符串
string ans; // p 型编码结果

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> s;

    ll n = s.size(); // 字符串长度
    ll i = 0; // 当前段的起点
    while (i < n) {
        ll j = i;
        // 向右扩展,直到字符不同或到达末尾
        while (j < n && s[j] == s[i]) {
            j++;
        }
        ll len = j - i; // 当前段长度
        // 输出段长和段字符
        ans += to_string(len);
        ans.push_back(s[i]);
        i = j; // 跳到下一个段的起点
    }

    cout << ans << '\n';
    return 0;
}