我已经使用优先级队列在Java中实现了霍夫曼编码算法,其中,我从根到叶遍历了树,并根据符号在输入中出现的次数获得了编码示例为#= 000011。一切都很好,树被很好地构建,编码正如预期的那样:但是我得到的输出文件的大小比原始文件大。我当前在遍历树的左节点和右节点时将'0'和'1'附加到字符串中。这是我的写方法,它使用OutputStream进行写:
private void writeToFile(Map<Byte, BitSet> dictCode, byte[] data, OutputStream os) throws IOException {
for (int i = 0; i < data.length; i++) {
os.write(dictCode.get(data[i]).toByteArray());
}
}
data
是我的文件(我将压缩的文件),以字节为单位
Map<Byte, BitSet> dictCode
BitSet是该字节的霍夫曼树代码路径
例如10的位集将为10={3}
,因为只有第三位为真:000100
我用字节写,为什么我的新文件比原始文件大?
答案 0 :(得分:0)
这里的问题似乎是您写的是字节流,而不是位流。
假设您的代码中 dictCode 映射在数据中的每个字节中都有一个平凡的条目,然后:
private void writeToFile(Map<Byte, BitSet> dictCode, byte[] data, OutputStream os) throws IOException {
for (int i = 0; i < data.length; i++) {
os.write(dictCode.get(data[i]).toByteArray());
}
}
为数据中的每个字节至少写入一个字节到 os 。因此,如果数据是输入文件中的原始字节,则永远无法使用此代码编写较小的文件。
例如,使用令牌流
111 010 000 1101 111
您正在写
00000111 00000010 00000000 00001101 00000111
代替
11101000 01101111
这就是为什么您看不到任何压缩的原因。