我想将霍夫曼代码保存到文件中。我怎样才能做到这一点? 我将霍夫曼代码保存为字符串,但生成的文件大小比原始文件大。
答案 0 :(得分:4)
一种非常简单的方法是一次写一位,如下所示:
unsigned char acc; // Accumulator of bit waiting to be written
int bitcount; // How many bits are aready present in the accumulator
// write a single bit (0/1)
void writebit(int bit)
{
acc |= (bit << bitcount);
if (++bitcount == 8)
{
writebyte(acc);
acc = 0;
bitcount = 0;
}
}
回读一个sigle位,程序是对称的
unsigned char acc; // bits waiting to be extracted
int bitcount; // how many bits are still available in acc
int readbit()
{
if (bitcount == 0)
{
bitcount = 8;
acc = readbyte();
}
--bitcount;
return (acc >> (7 - bitcount)) & 1;
}
当然这只是最简单的方法,但在您第一次能够保存并正确加载编码数据之前,我会先担心代码速度。
假设您有以下霍夫曼编码符号
A - 0
B - 10
C - 110
D - 111
并且您要对序列进行编码
A B A A C D A D B B
然后你会按顺序打电话
writebit(0); // A
writebit(1); writebit(0); // B
writebit(0); // A
writebit(0); // A
writebit(1); writebit(1); writebit(0); // C
writebit(1); writebit(1); writebit(1); // D
writebit(0); // A
writebit(1); writebit(0); // B
writebit(1); writebit(0); // B
因此写入的实际字节数为
(01100010) = 0x62
(01010111) = 0x57
(请注意,显示的代码从最低有效位开始,即如果要识别符号,则应从右到左读取括号内的位序列。)
答案 1 :(得分:3)
答案 2 :(得分:1)
我相信你保存的是一串1和0。真正的霍夫曼代码需要以二进制形式保存,然后再进行解析。如果你只是将输出保存为字符串,那么你就会破坏霍夫曼代码的目的,每个0和1都是8位而不是1。
答案 3 :(得分:1)
您可能正在为每个模式/字母保存整个字节。
假设e是最常见的字母。它的位模式为0。
假设z是最不常见的字母,它将从1开始有一些模式。让我们将它指定为1111 111.
您要撰写的文件将是:
0111 1111
你可能会写这个:
<00> 0000 0000 0111 1111。您需要利用按位运算来执行此操作。