{ }codelper
拼接构建字符串遍历字符串P0027

游程压缩

给出一个由小写英文字母组成的字符串。
对每一段连续相同的字母,依次写出该字母和它连续出现的次数,输出为一行。
例如 "aaabcc" 是 3 个 a、1 个 b、2 个 c,所以答案是 "a3b1c2"。
次数为 1 也要写 1,不相邻的相同字母属于不同的段("aba" → "a1b1a1")。

输入
长度 1 到 5,000,仅小写字母
输出
压缩后的一行字符串
样例 1 · stdin
aaabcc
stdout
a3b1c2
样例 2 · stdin
zzzzzzzzzzzzy
stdout
z12y1
main.py
输入(stdin)

运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。

$ 就绪

请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。

其他语言怎么写?查看各语言题解 · 8 种语言题解

最常见的错误是漏掉最后一段。
如果写成“字母变化时输出前一段”,循环结束后还要把剩下的一段再输出一次。
用内层循环找到每段的结尾并立即输出,就不会有这个问题。
收集结果的方法:Python 收集到列表再 "".join,Java 和 C# 用 StringBuilder,C++ 对 std::string 用 +=,C 直接 printf("%c%d") 输出,JS/TS 收集到数组再 join(""),Craykon 用 out = out + s[i] + (j - i)。
在 Java 和 C# 中反复对字符串用 + 每次都会创建新字符串,结果越长越慢。
另外在 C 中用 '0' + count 只写一个字符,超过 9 的段就会出错。

Pythonmain.py · 10 行
s = input()parts = []i = 0while i < len(s):    j = i    while j < len(s) and s[j] == s[i]:        j += 1    parts.append(s[i] + str(j - i))    i = jprint("".join(parts))
JavaScriptmain.js · 10 行
const s = require("fs").readFileSync(0, "utf8").trim();const parts = [];let i = 0;while (i < s.length) {  let j = i;  while (j < s.length && s[j] === s[i]) j++;  parts.push(s[i] + (j - i));  i = j;}console.log(parts.join(""));
TypeScriptmain.ts · 11 行
import { readFileSync } from "node:fs";const s: string = readFileSync(0, "utf8").trim();const parts: string[] = [];let i = 0;while (i < s.length) {  let j = i;  while (j < s.length && s[j] === s[i]) j++;  parts.push(s[i] + (j - i));  i = j;}console.log(parts.join(""));
JavaMain.java · 18 行
import java.io.BufferedReader;import java.io.InputStreamReader; public class Main {    public static void main(String[] args) throws Exception {        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        String s = br.readLine().trim();        StringBuilder out = new StringBuilder();        int i = 0;        while (i < s.length()) {            int j = i;            while (j < s.length() && s.charAt(j) == s.charAt(i)) j++;            out.append(s.charAt(i)).append(j - i);            i = j;        }        System.out.println(out);    }}
C#Main.cs · 20 行
using System;using System.Text; class Program{    static void Main()    {        string s = Console.ReadLine().Trim();        var sb = new StringBuilder();        int i = 0;        while (i < s.Length)        {            int j = i;            while (j < s.Length && s[j] == s[i]) j++;            sb.Append(s[i]).Append(j - i);            i = j;        }        Console.WriteLine(sb.ToString());    }}
C++main.cpp · 16 行
#include <iostream>#include <string> int main() {    std::string s, out;    std::cin >> s;    size_t i = 0;    while (i < s.size()) {        size_t j = i;        while (j < s.size() && s[j] == s[i]) j++;        out += s[i];        out += std::to_string(j - i);        i = j;    }    std::cout << out << "\n";}
Cmain.c · 16 行
#include <stdio.h> static char s[5005]; int main(void) {    if (scanf("%5000s", s) != 1) return 0;    int i = 0;    while (s[i]) {        int j = i;        while (s[j] == s[i]) j++;        printf("%c%d", s[i], j - i);        i = j;    }    printf("\n");    return 0;}
Craykonmain.cray · 14 行
s = 控制台.读行().去空白();out = "";i = 0;当 (i < s.长度){    j = i;    当 (j < s.长度 && s[j] == s[i])    {        j++;    }    out = out + s[i] + (j - i);    i = j;}控制台.输出(out);