把数字串切成极大同字符段,每段输出长度加字符,线性扫描即可完成。
OJ: roj
题目 ID: 1145
难度:入门
标签:入门字符串游程编码groupbypython
创建: 2026-09-29 21:04
更新: 2026-10-05 03:27
题目描述
给定一个只含数字字符的字符串 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;
}