基于C++的游程编码解压实现求助
Hey there! Let's get that decompression function working properly for your run-length encoding (RLE) setup. First, let's recap how your encoder works: it replaces consecutive repeated characters with a count followed by the character, and leaves single characters (including spaces!) as-is. Your decompressor needs to reverse this logic, and we'll fix your messy code step by step.
First, Let's Diagnose the Issues in Your Current Code
Your existing decompress function has a few key problems:
- You're comparing characters directly to integers (like
compressed[i] <= 1)—this checks the ASCII value of the character, not the numeric value, which is totally wrong. - You're jumping ahead with
i++too early, which leads to skipping characters or incorrect indexing. - You aren't handling multi-digit counts (though your example uses single digits, your encoder would produce things like
"10a"for 10 repeated 'a's, so we need to account for that). - The logic flow is reversed: you should first check if a character is a digit (part of a count) before treating it as a single character.
The Corrected Decompression Code
Here's a working implementation that handles all cases, including multi-digit counts and spaces:
#include <string> #include <cctype> // Required for isdigit() void Decompress(std::string &compressed, std::string &original) { original.clear(); // Ensure we start with an empty result string int n = compressed.length(); int i = 0; while (i < n) { // Case 1: We've hit a digit (start of a count) if (isdigit(compressed[i])) { std::string countStr; // Collect all consecutive digits to form the full count (handles 10+, 100+, etc.) while (i < n && isdigit(compressed[i])) { countStr += compressed[i]; i++; } // Convert the digit string to an integer int count = std::stoi(countStr); // The next character is the one we need to repeat if (i < n) { char targetChar = compressed[i]; // Append the character 'count' times efficiently original.append(count, targetChar); i++; } } // Case 2: Non-digit character (single occurrence, like spaces or single letters) else { original += compressed[i]; i++; } } }
How This Works
Let's break down the key parts:
- Clear the result string: We start by clearing
originalto avoid appending to any existing content. - Loop through the compressed string: We use a
whileloop instead of aforloop to give us more control over incrementingi(since we might jump multiple positions when collecting digits). - Handle digits: When we hit a digit, we collect all consecutive digits to form the full count (so "123a" becomes a count of 123). We convert this string to an integer with
std::stoi. - Repeat the character: Using
string.append(count, targetChar)is a clean, efficient way to add the repeated character to the result. - Handle single characters: Any non-digit (like spaces, 'i', 'k', etc.) is added directly to the result, since they represent single occurrences from the original string.
Testing with Your Example
If you pass your compressed string "3a4h3i 3k2j2h ikl 6w4e2t" into this function, it will correctly output the original string: "aaahhhhiii kkkjjhh ikl wwwwwweeeett".
内容的提问来源于stack exchange,提问作者liasis

