Appearance
题目
已知字符集 {a, b, c, d, e, f, g, h},若各字符的哈夫曼编码依次是
0100, 10, 0000, 0101, 001, 011, 11, 0001
则编码序列 0100011001001011110101 的译码结果是( )。
错因
A
在第二个字符处就走偏。开头 0100 切出 a 没问题,剩下 011001001011110101;这里把前 4 位 0110 误读成 0000(c)——明明读的是 0,1,1,0 却记成 0,0,0,0。前缀码本身唯一可译,错的是位序识别。
B
把 a 之后的 011... 当成 0101... 切,于是匹配到 d。这是"看花眼"型错误:0101(d)和 0100(a)只差最后一位,0110(f 的前缀)又和它们都不同;不在草稿上把每一位标号就容易错位。
C
前两步 a, f 都对,但第三步把剩余 001001011110101 错切成 10 → b。问题在于忽略了"前缀码必须从当前位置开始尝试最长前缀匹配"——001 是 e 的合法编码,应该优先吃掉 3 位再继续;只取头 2 位 10 看似也是 b,但这样会跳过本该归 e 的那个 0。
总解析
关键:哈夫曼编码是前缀码——任何编码都不是另一个编码的前缀,因此译码时逐位贪心扫描即可,遇到匹配就切出一个字符,从下一位继续。
把编码表整理成查找形式:
| 编码 | 字符 | 编码 | 字符 |
|---|---|---|---|
0100 | a | 001 | e |
10 | b | 011 | f |
0000 | c | 11 | g |
0101 | d | 0001 | h |
逐段切分 0100011001001011110101(在每段下方标注位置):
| 步 | 起始位 | 取出 | 字符 | 长度 |
|---|---|---|---|---|
| 1 | 0 | 0100 | a | 4 |
| 2 | 4 | 011 | f | 3 |
| 3 | 7 | 001 | e | 3 |
| 4 | 10 | 001 | e | 3 |
| 5 | 13 | 011 | f | 3 |
| 6 | 16 | 11 | g | 2 |
| 7 | 18 | 0101 | d | 4 |
累计长度 ,恰好等于编码序列总位数,无残留。
译码结果:a f e e f g d。
最终答案是 D。
小提醒:题目里"哈夫曼编码依次是 ……"指的是按
a, b, c, d, e, f, g, h顺序对应给出,做题时务必先把编码表抄成上面那种"编码 → 字符"的反查表,否则正向匹配每一步都要在文字里翻一遍很容易出错。