问题描述
所以我正在尝试创建一个自适应霍夫曼编码算法,但遇到了一些我不知道如何解决的障碍。
我的算法完全按预期工作,除了一个小问题;当压缩结果不是每个字节都正好是 8 位时,我似乎无法弄清楚如何确保不会写入额外的字符。
举个例子;这是我输入文本的结尾片段
subscribe to our email newsletter to hear about new eBooks.
fa
这是同一文本经过编码然后解码后的结束片段
subscribe to our email newsletter to hear about new eBooks.
fa
as
额外的“as”字符是最终压缩位不是完整字节的一部分的结果;最后一个字节由位“0111”表示,程序内部将其识别为“00000111”,这会导致写入最后两个字符。除此之外,当我尝试将填充应用于该字节的末尾,使其被视为“01110000”时,结束片段如下所示。
subscribe to our email newsletter to hear about new eBooks.
fa
r
这稍微好一点,但额外的“r”字符被写入,因为这种编码的“r”的代码是“0000”,导致这种复杂化。
我该如何避免这种情况?
如果这意味着什么,为了获取位,我正在使用以下代码块操作一个包含 1 和 0 序列的编码字符串。
split 是一个字符串数组,其中字符串被拆分为 8 个字符,而 list 是一个 ArrayList,其中包含存储的整数列表,以便稍后输出为二进制表示的字符串。
String[] split = frankenstein.encodedString.split("(?<=\\G.{8})");
for (int i = 0; i < split.length; i++) {
String str = split[i];
//Adds 0 padding at the end of the bits if it's necessary
if (i == split.length - 1) {
if (str.length() != 8) {
for (int j = str.length(); j < 8 ;j++)
str += "0";
}
}
list.add(Integer.parseInt(str,2));
}
解决方法
要么 a) 在编码消息之前发送要解码的字符数,要么 b) 包括一个唯一的流结束符号作为您正在编码的最后一个符号。后者的一个例子是,如果您要编码范围为 0..255 的字节,请在末尾添加一个值为 256 的符号,该符号不能出现在前面的数据中。