您无需创建代码或树即可解码规范代码。您所需要的只是按顺序排列的符号列表以及每个代码长度中的符号数。 “按顺序”是指按码长从最短到最长排序,在每个码长内,按符号值排序。
由于代码长度内的规范代码是连续的二进制整数,您可以简单地进行整数比较以查看您拥有的位是否在该代码范围内,如果是,则进行整数减法以确定它是哪个符号。
下面是来自puff.c 的代码(稍作更改),以明确显示这是如何完成的。 bits(s, 1) 从流中返回下一位。 (假设总是有下一位。)h->count[len] 是按长度编码的符号数量len 代码,其中len 在0..MAXBITS 中。如果将h->count[1]、h->count[2]、...、h->count[MAXBITS] 相加,即为编码符号的总数,即为h->symbol[] 数组的长度。 h->symbol[] 中的第一个 h->count[1] 符号长度为 1。h->symbol[] 中的下一个 h->count[2] 符号长度为 2。以此类推。
h->count[] 数组中的值(如果正确)被限制为不会超额订阅可在len 位中编码的可能代码数量。可以进一步限制它表示完整的代码,即没有未定义的位序列,在这种情况下decode() 不能返回错误 (-1)。要使代码完整且不会超额订阅,h->count[len] << (MAXBITS - len) 与所有 len 的总和必须等于 1 << MAXBITS。
简单的例子:如果我们用一位编码e,用两位编码t,用三位编码a和o,那么h->count[]就是{0, 1, 1, 2}(第一个值,@ 987654347@ 未使用),而h->symbol[] 是{'e','t','a','o'}。那么e的代码是0,t的代码是10,a是110,o是111。
#define MAXBITS 15 /* maximum bits in a code */
struct huffman {
short *count; /* number of symbols of each length */
short *symbol; /* canonically ordered symbols */
};
int decode(struct state *s, const struct huffman *h)
{
int len; /* current number of bits in code */
int code; /* len bits being decoded */
int first; /* first code of length len */
int count; /* number of codes of length len */
int index; /* index of first code of length len in symbol table */
code = first = index = 0;
for (len = 1; len <= MAXBITS; len++) {
code |= bits(s, 1); /* get next bit */
count = h->count[len];
if (code - count < first) /* if length len, return symbol */
return h->symbol[index + (code - first)];
index += count; /* else update for next length */
first += count;
first <<= 1;
code <<= 1;
}
return -1; /* ran out of codes */
}