Appearance
题目
5 个字符有如下 4 种编码方案,不是前缀编码的是( )。
错因
A
直觉觉得"01 短,0001 长,可能 01 是 0001 的前缀"——但01 比对 0001 时第二个字符是 1 vs 0,不一致,所以 01 不是 0001 的前缀。其实 A 的所有编码两两都不互为前缀(可逐对验证),是合法的前缀编码,被错判了。
B
类似地,看到 010、011、001 都很相似就以为有前缀关系,但它们都是长度 3——同长度编码只要不完全相同就不可能互为前缀,B 是合法前缀编码。
C
"5 个长度都是 3 的编码"看起来太规整,被怀疑"是不是哪里重复"。其实等长编码 + 编码各不相同 = 自动是前缀编码,C 是合法的(甚至是定长编码这一类的代表)。
总解析
前缀编码的定义:编码集合中,任何一个编码都不是另一个编码的前缀。这样可以做唯一可译——读到一个完整编码就能立刻翻译,不需要分隔符。
判定方法:把所有编码两两比较——若较短的一个是较长那个的开头若干字符,就违反前缀性质。
逐选项检查:
| 选项 | 短串 → 长串 | 是否构成前缀 | 结论 |
|---|---|---|---|
| A | 01 vs 0000:第 2 位 1 vs 0 不同 ✗;01 vs 0001:第 2 位不同 ✗;01 vs 001:第 2 位不同 ✗;其他对均不互为前缀 | 无 | ✓ 合法前缀编码 |
| B | 全部 5 个编码长度均为 3,互不相同 → 同长度天然不互为前缀;与 1(长度 1)比:011/000/001/010 首位都是 0,1 不是它们前缀 | 无 | ✓ 合法前缀编码 |
| C | 全部长度 3 且互不相同 → 同长度不互为前缀 | 无 | ✓ 合法前缀编码(这是定长编码) |
| D | 检查 110 和 1100:110 是 1100 的前 3 个字符——110 是 1100 的前缀 | 有 | ✗ 不是前缀编码 |
D 中存在 110 ⊏ 1100——读到 1100… 时无法判断该取 110 接着读 0 还是直接取整个 1100,译码会歧义,所以 D 不是合法前缀编码。
快速检查技巧:把所有编码按长度从短到长排序,再用每个短编码当模板去
startsWith测一遍后面所有长编码,发现一对就立即判定"非前缀编码"。
本题:D 中长度排序是0, 100, 110, 1100, 1110——0vs100首位不同 ✓;0vs110/1100/1110首位不同 ✓;100vs1100/1110第 2 位不同 ✓;110vs1100前 3 位110完全相同 ✗ —— 命中。
最终答案是 D。