C++行程长度解码问题:无法处理多位数(禁用字符串/数组)
Got it, let's break down why your current code struggles with multi-digit counts like 12 in a12bhr, and fix it without using strings or arrays.
The Problem with Your Current Code
Your code only handles single-digit numbers. When it encounters 12 in a12bhr:
- It reads
1, setscounter=1, does nothing (sincecounter>1is false), then updatesvorigeKarto1. - Next it reads
2, setscounter=2, then outputsvorigeKar(which is now1) once. - Finally it reads
band outputs it.
The result is a1bhr instead of the expected aaaaaaaaaaaaabhr—totally wrong, because it treats 1 and 2 as separate counts, not the single number 12.
The Solution: Accumulate Multi-Digit Numbers On-the-Fly
Since you can't use strings or arrays, we'll build the full number using integer arithmetic. When we hit a digit, we keep reading consecutive digits and combine them into a single integer (e.g., 1 + 2 becomes 12). Then we use that integer to repeat the previous character the correct number of times.
Here's the corrected code:
#include <fstream> using namespace std; int main() { ifstream invoer("encoded.txt"); ofstream uitvoer("decoded.txt"); if (!invoer.is_open() || !uitvoer.is_open()) { return 1; // Handle file open failure } char kar, vorigeKar; invoer.get(kar); // Read first character before starting loop while (!invoer.eof()) { if (kar >= '0' && kar <= '9') { int count = 0; // Accumulate all consecutive digits into a single number while (kar >= '0' && kar <= '9') { count = count * 10 + (kar - '0'); invoer.get(kar); } // Put the non-digit character back into the input stream invoer.unget(); // Output the previous character (count-1) times // We subtract 1 because we already output the character once earlier for (int i = 1; i < count; ++i) { uitvoer.put(vorigeKar); } // Read the non-digit character to process in the next loop iteration invoer.get(kar); } else if (kar == '/') { // Handle escape character: read the next character and output it invoer.get(kar); uitvoer.put(kar); vorigeKar = kar; invoer.get(kar); } else { // Regular character: output it and track it as the previous character uitvoer.put(kar); vorigeKar = kar; invoer.get(kar); } } invoer.close(); uitvoer.close(); return 0; }
Key Fixes Explained
- Multi-Digit Accumulation:
- When we hit a digit, we enter an inner loop that keeps reading digits, updating
countwithcount = count * 10 + (kar - '0'). This turns sequences like1followed by2into the integer12.
- When we hit a digit, we enter an inner loop that keeps reading digits, updating
- Unget Non-Digit Characters:
- After reading all digits, we hit a non-digit character. We use
invoer.unget()to put this character back into the input stream so the outer loop can process it normally.
- After reading all digits, we hit a non-digit character. We use
- Correct Repetition:
- We output
count-1copies ofvorigeKarbecause we already output the original character once before hitting the number (e.g.,a12already hadaoutput, so we add 11 moreas to make 12 total).
- We output
- Loop Initialization:
- We read the first character before starting the loop to avoid common
eof()edge cases where the loop runs an extra time after the last character is read.
- We read the first character before starting the loop to avoid common
Testing with Your Examples
- For
a12bhr: The code accumulates12as the count, outputs 11 extraas, then processesb,h,rnormally—resulting inaaaaaaaaaaaaabhr. - For
hel2o: It accumulates2, outputs 1 extral, resulting inhello. - For
a10jkle: It accumulates10, outputs 9 extraas, resulting inaaaaaaaaaaajkle.
内容的提问来源于stack exchange,提问作者VdeJ

