Java RLE解码实现咨询:嵌套循环逻辑错误与数组越界问题
修正RLE解码逻辑的解决方案
首先得指出你现有代码里的核心问题:
- 内层循环错误地用了解码后的数组长度
initialLength作为遍历上限,但实际上你应该遍历**压缩数组rleData**的长度,这直接导致了数组越界的报错。 - 嵌套循环的逻辑完全不符合RLE解码的需求——你现在的代码会把所有奇数索引的byte反复赋值给解码数组的每个位置,完全没处理「按次数重复值」的核心逻辑。
正确的解码思路
RLE压缩数组的结构是**[次数1, 值1, 次数2, 值2, ...]**,所以我们需要:
- 遍历压缩数组,每次处理一对元素(偶数索引是重复次数,奇数索引是对应的值)。
- 把次数对应的byte转为无符号int(Java的byte是有符号的,比如
0xFF作为byte是-1,但实际代表255次,必须转成无符号才能正确获取次数)。 - 将对应的值重复指定次数,依次填充到解码后的数组中。
修正后的代码实现
public static byte[] decodeRle(byte[] rleData) { int initialLength = getDecodedLength(rleData); byte[] returnDecoded = new byte[initialLength]; int currentPos = 0; // 记录解码数组当前填充的位置 // 每次遍历一对(次数+值),步长设为2 for (int i = 0; i < rleData.length; i += 2) { // 将byte转为无符号int,避免负数次数的问题 int repeatCount = Byte.toUnsignedInt(rleData[i]); byte targetValue = rleData[i + 1]; // 把目标值重复指定次数,填充到解码数组 for (int j = 0; j < repeatCount; j++) { returnDecoded[currentPos++] = targetValue; } } return returnDecoded; }
关键细节说明
- byte转无符号int:用
Byte.toUnsignedInt()方法,确保像(byte)0xFF这样的负数被正确转换为255,而不是-1,这是RLE解码里很容易踩的坑。 - 跟踪填充位置:用
currentPos变量记录解码数组当前的填充位置,每添加一个元素就自增,避免了外层循环直接遍历解码数组长度的错误逻辑。 - 步长遍历压缩数组:每次循环
i += 2,确保我们每次处理的都是合法的「次数-值」对(前提是你的压缩数组是合法的,长度为偶数)。
测试你的示例
对于输入{3, 15, 6, 4}:
- 第一次循环:repeatCount=3,targetValue=15,填充3个15到解码数组,currentPos变为3。
- 第二次循环:repeatCount=6,targetValue=4,填充6个4到解码数组,currentPos变为9。
- 最终解码数组就是
{15,15,15,4,4,4,4,4,4},完全符合预期。
内容的提问来源于stack exchange,提问作者Noodles
相关产品推荐
相关产品推荐

