Easy–medium · strings
Run-Length Encoding
Scan the line with a single pointer: whatever character you are standing on, count how many times it repeats, print it with its count, and you are already past that whole run. No nested loops over the string — the counter IS the inner loop.
At a glanceWalk with one index: at each position, count the run of identical characters, print the character and the count (always, even 1 — a10 is legal), and continue after the run.
Problem
Input: One line of 1 to 200 lowercase letters, no spaces.
Output: The run-length encoding: for every maximal run, the character followed by its count. The count is always printed, even when it is 1.
Samples:
| Input | Output |
|---|---|
aaabbc | a3b2c1 |
a | a1 |
Counts can reach double digits: a run of 10 identical letters prints as a10, two characters of output for a run of 10 — that is the whole point of compression.
Your solution
Custom input for "Run my input"
Judging runs in your browser against hidden tests. A runaway loop is cut off after 3 seconds — still, make sure every loop has an exit. Your code is saved in this browser as you type.
Stuck? Hints
Hint 1 — The run ends itself
Stand on position i and count while s[i] == c. When the count loop exits, i is already pointing at the next run's first character — there is nothing to skip, nothing to reset except the counter. One pointer through the whole string, never backwards.
Hint 2 — Counts are printed as numbers
cout << count handles one digit, two digits, three digits — no manual digit splitting needed, that was the binary-representation problem's job. But note what is required: printing the count even when it is 1. An output of abc for abc feels natural and is wrong.
Hint 3 — Read the whole line
One more lap on the cin.getline lesson: there are no spaces here, but getline is still the right reader for a line that must be taken as a whole — and it leaves no Enter behind to poison a later read. You met the full argument in Reverse the Words.
Solution (try it first!)
#include <iostream>
using namespace std;
int main() {
char s[205];
cin.getline(s, 205);
int i = 0;
while (s[i] != '\0') {
char c = s[i];
int count = 0;
while (s[i] == c) {
count++;
i++;
}
cout << c << count;
}
cout << endl;
return 0;
}
Run-length encoding is the ancestor of real compression (it lives inside fax, JPEG and PNG pipelines), and here it is also the state-machine string pattern again: one flag, one counter, no lookahead. Its counting cousin — counting runs of a *kind* instead of runs of a *character* — is Count the Words.
Deep dive
Why this works
One forward pointer with a self-terminating inner count: the moment s[i] stops matching c, i is already at the next run. No second index, no lookahead, no second pass — the counter is the inner loop, and the string encodes its own segmentation.
The cost
O(L) time for a line of L characters — every character is visited exactly once by the outer pointer — and O(L) space for the output, which is never longer than the input here.
Where it goes wrong
- Skipping the count when it is 1 feels tidier and is wrong: the spec says always print it, and 'a' must come out as a1.
- Reading with
cin >>would stop at the first space (none here, but the habit matters) — and more importantly getline is the whole-line reader this format assumes. - Printing the separator between count and next character is automatic — there is none; the format is char immediately followed by digits.
Next step
The same one-flag-one-counter scan, counting runs of a *kind* (spaces) instead of runs of a character, is Count the Words.
Two things to remember
- The inner count loop IS the segmentation — i lands on the next run for free.
- Print the count always, even 1; cout handles multi-digit numbers.
🐞 This version fails — open it and try
Skips the count when it is 1 — the judge wants a1, not a
#include <iostream>
using namespace std;
int main() {
char s[205];
cin.getline(s, 205);
int i = 0;
while (s[i] != '\0') {
char c = s[i];
int count = 0;
while (s[i] == c) {
count++;
i++;
}
cout << c;
if (count > 1) cout << count; // bug: count of 1 is required too
}
cout << endl;
return 0;
}