{ }codelper
文字列の組み立て文字列の走査P0027

同じ文字をまとめて縮める

英小文字からなる文字列が与えられる。
同じ文字が続いているまとまりごとに、その文字と続いた個数を順につなげて一行で出力せよ。
たとえば "aaabcc" は a 3 個、b 1 個、c 2 個なので "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 と一文字だけ書くと、10 個以上のまとまりが壊れます。

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);