再战commafree code——暴力挑选&优化
引言
在上一篇文章中,我们生成了参数 m=3、n=4 时的所有可能 commafree code。本文将介绍如何从这18个码中挑选出一个最大的子集,使其满足 commafree code 的性质:当集合中任意两个码相连接时,不考虑首尾各n个字母后,中间所有长度为n的子串都不在这个集合中。
由于一个码可以和自身连接,比如选择0001后,序列00010001中的所有长度为4的中间子串(0010、0100、1000)都不能出现在最终集合中。这意味着如果我们选择了某个码,它的所有循环移位都不能再加入集合。因此,对每个主码,我们只需要从它的4个循环移位中选择一个加入集合。
commafree code初次见面——生成
引言
commafree code 是一种自同步定长编码,和 Huffman 编码那种变长压缩码完全不同。给定 m 个字母构成的长度为 n 的码字集合 D,若任意两个码字 \(x_1x_2x_3x_4\) 与 \(x_5x_6x_7x_8\) 相邻时,中间的偏移子串 \(x_2x_3x_4x_5\)、\(x_3x_4x_5x_6\)、\(x_4x_5x_6x_7\) 均不在 D 中,则称 D 为 commafree code(又称自同步块码)。这一性质保证接收方无需分隔符即可正确分段解码。
以 n=4 为例:”likethis”中 “like” 和 “this” 是码字,而中间的偏移串 “iket”、”keth”、”ethi” 均不是码字。另外,自身循环串(如 dodo、gaga)不能成为码字,因为两个相同码字相邻后中间的偏移子串就是自身。
利用链表回溯生成 Langford 对
引言
我发现在以前的回溯算法中,很少提到链表的使用,虽然 Dancing link 算法已经用的炉火纯青了,但介绍它属于是“跳级”了,咱们既然从零单排回溯算法,那还要从链表在回溯中的简单用法讲起,这就要提 Langford 对的生成了。
Langford 对是一个组合数学中的概念。给定一个正整数 ,Langford 对是将数字 1 到 n 的每个数字重复两次,并以一种特定的方式排列,使得两个相同的数字之间恰好间隔等于该数字的位置数。 例如,对于 n=4,一种可能的 Langford 对排列是 23421314。在这里,每个数字重复两次,且两个 1 之间间隔 1 个位置;两个 2 之间间隔 2 个位置;以此类推。