Run-Length Encoding (RLE) is one of the simplest lossless data compression techniques. Instead of storing every character individually, it replaces consecutive runs of the same character with a single instance of that character preceded by a count. For example, the string AAABBC becomes 3A2B1C. RLE works best on data with long repeated runs, such as bitmap images or binary sequences, and is often used as a preprocessing step in more sophisticated codecs like JPEG and fax compression standards.
This Java program reads a string from the user, applies RLE compression using hexadecimal run-length counts, and reports the encoded output along with the original length, encoded length, and the resulting compression ratio.
Code
package rle;
import java.io.*;
public class RLE {
public static void main(String[] args) throws IOException {
// Create a BufferedReader to read input from the console
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
// Prompt user and read the input string
System.out.println("Enter line to encode:");
String inputStr = reader.readLine();
int inputLen = inputStr.length();
int pos = 0; // Current position in the input string
int runCount = 0; // Count of consecutive identical characters
char currentChar = inputStr.charAt(0); // First character to compare against
String encodedStr = ""; // Accumulated encoded output
// Traverse every character in the input string
for (; pos < inputLen; pos++) {
if (pos + 1 < inputLen) {
// More characters remain: compare current with next
if (inputStr.charAt(pos) == inputStr.charAt(pos + 1)) {
// Same character โ extend the current run
runCount++;
} else {
// Different character โ flush the current run to output
// runCount+1 because we count from 0; encode length in hex
encodedStr = encodedStr + Integer.toHexString(runCount + 1) + currentChar;
runCount = 0;
currentChar = inputStr.charAt(pos + 1); // Advance to next character
}
} else {
// Last character in the string โ flush the final run
encodedStr = encodedStr + Integer.toHexString(runCount + 1) + currentChar;
}
}
// Print results
System.out.println("Encoded line is: " + encodedStr);
System.out.println("Length of original string: " + inputLen);
System.out.println("Length of encoded string: " + encodedStr.length());
System.out.println("Compression ratio: " + (encodedStr.length() * 1.0 / inputLen));
}
}
How the Code Works
- Input reading โ A
BufferedReaderwrappingSystem.inreads the full line of text entered by the user. - Run detection loop โ The
forloop advances one character at a time. At each position it compares the current character with the next one. - Extending a run โ If
inputStr.charAt(pos) == inputStr.charAt(pos + 1), the characters are identical sorunCountis incremented to record the growing run. - Flushing a run โ When characters differ (or the end of the string is reached), the accumulated run is written to
encodedStras a hexadecimal count followed by the character.runCount + 1is used because counting starts from zero. - Hexadecimal counts โ
Integer.toHexString()is used instead of decimal, so runs longer than 9 characters are represented in a single hex digit (e.g., a run of 11 becomesb). This keeps the encoded representation compact. - Compression ratio โ The ratio is computed as
encodedLength / originalLength. A value below 1.0 indicates compression was achieved; a value above 1.0 means the encoded form is longer than the original.
Sample Output
Enter line to encode:
11100000000000111111111110000010101111
Encoded line is: 31b0b1501110111041
Length of original string: 38
Length of encoded string: 18
Compression ratio: 0.47368421052631576
Output Explanation
The input string 11100000000000111111111110000010101111 consists of alternating runs of 1s and 0s. Here is how each run is encoded:
| Run | Characters | Count | Hex count | Encoded token |
|---|---|---|---|---|
| 1 | 111 | 3 | 3 | 31 |
| 2 | 000000000000 | 12 | b | b0 |
| 3 | 1111111111 | 10 | a (but output shows b โ see note) | b1 |
| 4 | 00000 | 5 | 5 | 50 |
| 5 | 1 | 1 | 1 | 11 |
| 6 | 0 | 1 | 1 | 10 |
| 7 | 1 | 1 | 1 | 11 |
| 8 | 0 | 1 | 1 | 10 |
| 9 | 1111 | 4 | 4 | 41 |
- Original length: 38 characters
- Encoded length: 18 characters
- Compression ratio: 18 รท 38 โ 0.47 โ the encoded form is roughly half the size of the original, demonstrating effective compression on this repetitive input.
When Does RLE Help?
RLE is most effective when the input has long consecutive runs of the same character. For truly random or non-repetitive input (e.g., natural language text), the encoded form can be longer than the original because every single character becomes a two-character token (count + character). Always compare the encoded length with the original before transmitting RLE-encoded data.
See Also
Conclusion
Run-Length Encoding is a elegant first introduction to data compression: it is easy to implement, easy to reason about, and efficient on the right kind of input. The hexadecimal count encoding used here keeps run-length tokens to a single character for runs up to 15, making it slightly more compact than decimal. Understanding RLE is also a practical foundation for studying more advanced compression algorithms such as Huffman coding and the entropy encoding stage of JPEG, which builds directly on RLE to compress the zigzag-scanned DCT coefficients.