java RLE程序出现问题,(游程长度编码)

bnlyeluc  于 2023-05-21  发布在  Java
关注(0)|答案(1)|浏览(162)

我如何才能使测试工作?我没有在代码中遇到错误。Java对我来说是新的,我正在学习它。我知道这个问题与阵列有关,但我不知道如何修复它。
解压缩错误:
“数组长度不同,预期。长度=2实际。长度=5;数组第一次在元素[2]处不同;“
压缩错误:
“数组长度不同,预期。长度=3实际。长度=2;数组第一次在元素[0]处不同;“
代码:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class RLE {
    public static void compress(InputStream is, OutputStream os) throws IOException {
        int currentByte = is.read();
        int count = 1;

        while (currentByte != -1) {
            int nextByte = is.read();

            if (nextByte == currentByte && count < 255) {
                count++;
            } else {
                os.write((byte) count);
                os.write((byte) currentByte);
                count = 1;
            }

            currentByte = nextByte;
        }

        os.flush();
        is.close(); 
        os.close(); 
    }

    public static void decompress(InputStream is, OutputStream os) throws IOException {
        int currentByte = is.read();

        while (currentByte != -1) {
            int count = currentByte;
            int value = is.read();

            byte[] bytes = new byte[count];
            for (int i = 0; i < count; i++) {
                bytes[i] = (byte) value;
            }

            os.write(bytes);
            currentByte = is.read();
        }

        os.flush();
        is.close(); 
        os.close(); 
    }
}

测试:

import java.io.*;

import static org.junit.Assert.*;

public class RLETest {

    private void test1(byte[] expected, byte[] input) throws Exception {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        RLE.compress(new ByteArrayInputStream(input), bos);
        assertArrayEquals(expected, bos.toByteArray());
    }

    private void test2(byte[] expected, byte[] input) throws Exception {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        RLE.decompress(new ByteArrayInputStream(input), bos);
        assertArrayEquals(expected, bos.toByteArray());
    }

    @org.junit.Test
    public void compress() throws Exception {
        test1(new byte[]{1,1,4}, new byte[]{1,1,1,1,1,1});
        test1(new byte[]{1,1,0}, new byte[]{1,1});
        test1(new byte[]{1,2,3}, new byte[]{1,2,3});
        test1(new byte[]{1, 1, 0, 2, 2, 0, 3, 3, 0}, new byte[]{1, 1, 2, 2, 3, 3});
        test1(new byte[]{1, 2, 3, 3, 1, 4}, new byte[]{1, 2, 3, 3, 3, 4});
        test1(new byte[]{1,2,3,3,0}, new byte[]{1, 2, 3, 3});

        byte[]ar;

        ar = new byte[260];
        for (int i = 0; i < ar.length; i++) {
            ar[i] = 100;
        }

        test1(new byte[]{100,100,(byte) 255, 100, 100, 1}, ar);

        ar = new byte[550];
        for (int i = 0; i < ar.length; i++) {
            ar[i] = 100;
        }

        test1(new byte[]{100,100,(byte) 255, 100, 100, (byte) 255, 100, 100, 34}, ar);
    }

    @org.junit.Test
    public void decompress() throws Exception {
        test2(new byte[]{5,5}, new byte[]{5,5,0});
        test2(new byte[]{1,2,3}, new byte[]{1,2,3});
        test2(new byte[]{1,2,2,3}, new byte[]{1,2,2,0,3});
        test2(new byte[]{1,2,3,3,3,3}, new byte[]{1,2,3,3,2});
        test2(new byte[]{5}, new byte[]{5});
        test2(new byte[]{1,1,2,2,3,3,4,4}, new byte[]{1,1,0,2,2,0,3,3,0,4,4,0});

        byte[]ar;

        ar = new byte[202];
        for (int i = 0; i < ar.length; i++) {
            ar[i] = 55;
        }

        test2(ar, new byte[]{55,55,(byte)200});

        ar = new byte[259];
        for (int i = 0; i < ar.length; i++) {
            ar[i] = 55;
        }

        test2(ar, new byte[]{55,55,(byte)255, 55, 55, 0});
    }

}
vyswwuz2

vyswwuz21#

在Java中,byte值是有符号的,所以它的范围是从-128到127。
而不是0到255的范围。
你可以采取两种方法。我将展示两者。
作为解决方案,您可以将第13行count < 255的检查值减少到127。
为了增加持久性,可以使用Byte.MAX_VALUE

if (nextByte == currentByte && count < 127) {
    count++;
} else {
    os.write((byte) count);
    os.write((byte) currentByte);
    count = 1;
}

或者,您可以在decompression方法中对count值进行位掩码。

count = currentByte & 0xff;

这将为负的byte值返回正值。
举个例子。

-1 & 0xff == 255

此外,作为建议,您可以减少compressdecompress方法。
compress内容放在try-finally块中。
这样,您就可以在发生IOException时关闭流。
并且,通过将nextByte的声明置于while循环之外,来增加nextByte的作用域。

public static void compress(InputStream is, OutputStream os) throws IOException {
    try {
        int currentByte = is.read();
        int nextByte;
        int count = 1;
        while (currentByte != -1) {
            nextByte = is.read();
            if (nextByte == currentByte && count < 255)
                count++;
            else {
                os.write((byte) count);
                os.write((byte) currentByte);
                count = 1;
            }
            currentByte = nextByte;
        }
    } finally {
        os.flush();
        is.close();
        os.close();
    }
}

对于decompress方法,同样的情况,将内容放在try-finally块中。
您的currentByte赋值可以放在while条件语句中。
而且,您可以使用Arrays.fill方法来填充bytes数组。

public static void decompress(InputStream is, OutputStream os) throws IOException {
    try {
        int currentByte;
        int count, value;
        byte[] bytes;
        while ((currentByte = is.read()) != -1) {
            count = currentByte & 0xff;
            value = is.read();
            bytes = new byte[count];
            Arrays.fill(bytes, (byte) value);
            os.write(bytes);
        }
    } finally {
        os.flush();
        is.close();
        os.close();
    }
}

作为一个附加的度量,只是为了演示当将大于127的值分配给byte时会发生什么。
考虑以下情况,我们将从125开始,递增1,4倍,以达到129。

byte value;
String binary;
for (int count = 1; count < 5; count++) {
    value = (byte) (125 + count);
    System.out.printf("+%d, ", count);
    System.out.printf("value= %4d, ", value);
    binary = "%8s".formatted(Integer.toBinaryString(value));
    binary = binary.substring(binary.length() - 8);
    System.out.printf("%s%n", binary);
}
+1, value=  126,  1111110
+2, value=  127,  1111111
+3, value= -128, 10000000
+4, value= -127, 10000001

相关问题