您的选择:
自动大写:
使用大写的通用算法,使用以下技术之一仅记录生成的大写和实际大写之间不同的字母。要重新生成,只需再次运行算法并翻转所有记录字母的大写。假设应该有大写字母(例如句子的开头),这将稍微减慢算法速度(仅以 n 的一个小常数因子,并且体面的压缩通常比这慢得多)并且总是减少存储量少数人需要的空间。
资金头寸位图:
你已经介绍过这个,不是特别有效。
带有识别字符的大写前缀:
也已经涵盖,除了您描述了后缀,但前缀通常更好,并且,对于更通用的解决方案,您还可以转义^
with ^^
。不是一个坏主意。根据压缩情况,改用数据集中已经出现的字母可能是个好主意。最常见或最不常见的字母,或者您可能必须查看压缩算法并进行大量处理以确定要使用的理想字母。
以任何格式存储与开始的资本距离:
与下一个首都的距离没有优势(下)。
到下一个大写字母的距离 - 非位串表示:
通常比使用位串效率低。
位串 = 到下一个大写字母的距离:
您有一系列长度,每个长度依次表示大写字母之间的距离。因此,如果我们有距离0,3,1,0,5
,大写如下:(AbcdEfGHijklmNo
第一个跳过 0 个字符,第二个跳过 3 个字符,第三个跳过 1 个字符,等等)。有一些选项可用于存储它:
固定长度:不是一个好主意,因为它需要 = 可能的最长距离。一个明显的替代方法是将某种溢出到下一个长度,但这仍然使用太多空间。
固定长度,不同的设置:最好用一个例子来解释——前4位表示长度,00
表示后面有2位表示距离,01
表示4位,10
表示8位,11
表示16位,如果有超过 16 位的机会,您可能想要执行类似的操作 -110
表示 16 位、1110
表示 32 位、11110
表示 64 位等(这听起来可能类似于确定 IPv4 地址的类别)。所以0001010100
会分裂成00
- 01
, 01
-0100
,因此距离为 1、4。请注意,长度不必以 2 的幂为单位递增。16 位 = 65535 个字符很多,2 位 = 3 很少,您可以将其设为 4、6、 8, (16?), (32?), ??? (除非连续有几个大写字母,那么您可能也需要 2 位)。
使用转义序列变长:假设转义序列是00
,我们要使用所有不包含 的字符串00
,所以位值表如下所示:
Bits Value
1 1
10 2
11 3
101 4 // skipped 100
110 5
111 6
1010 7 // skipped 1000 and 1001
10100101010010101000101000010
将分成101
, 10101
, 101010
, 101
, 0, 10
. 请注意,这...1001..
只是导致在左侧 1 处结束的拆分和从右侧 1 开始的拆分,并...10001...
导致在第一个 0 处结束的拆分和从右侧 1 开始的拆分,并...100001...
表示两者之间的 0 值距离。伪代码类似于:
if (current value == 1 && zeroCount < 2)
add to current split
zeroCount = 0
else if (current value == 1) // after 00...
if (zeroCount % 2 == 1) { add zero to current split; zeroCount--; }
record current split, clear current split
while (zeroCount > 2) { record 0-distance split; zeroCount -= 2; }
else zeroCount++
对于短距离来说,这看起来是一个很好的解决方案,但是一旦距离变大,我怀疑您开始跳过太多值并且长度会迅速增加。
没有理想的解决方案,它在很大程度上取决于数据,您必须使用前缀大写字母和位串距离的不同选项来查看哪个最适合您的典型数据集。