2010-04-01 73 views

回答

4

将8个字节视为一个64位无符号整数,并将其转换为十进制,并用零填充到左边。这应该使尽可能短的字符串,因为它利用除了开始的所有位置上的所有可用数字。

如果你的数据不是均匀分布的,还有其他的选择,考虑霍夫曼编码,以便最常用的数据模式可以用较短的字符串表示。一种方法是使用第一位数字来编码字符串的长度。除第一位以外的所有数字都可以视为长度说明符。这样,最多20个数字的长度永远不会超过。 (第20位数字只能是0或1,最高的64位数字是18,446,744,073,709,551,615。)将其他数字精确解释为长度的映射应基于您的模式分布。如果你有10种模式发生,你经常可以例如reserv“0”表示一个数字表示一个完整的序列。

然而,任何这种更复杂的编码都会引入对更复杂的打包/解包代码甚至查找表的需求,因此可能不值得付出努力。

+1

... 64位(无符号)整数... – 2010-04-01 07:58:42

+1

但它也将是可变长度,这需要流之间的块之间的分隔符,这将是....? (因为所有十位数已被使用。):-) – 2010-04-01 07:59:02

+0

感谢您的评论,我已经更正并延长了我的答案。 – 2010-04-01 08:04:56

1

具有最短长度的结果是将其直接转换为小数。这导致最高值为18446744073709551615,但如果没有任意长度的整数能力,转换可能会很困难。

下一个最长的是将它转换为八进制为一个块。这导致最大长度为22,值为1777777777777777777777。这只需要转换,并且可以很容易地处理。

下一个最长的是将其转换为八进制或十进制的字节。这导致长度为24,分别有8次重复377255。来回转换是微不足道的,作为读者的练习。

+0

感谢您的回答。对于没有任意长度的整数能力的第一个选项是困难的,这不是一个真正的问题。您可以将块分成4个字节的整数,将它们分别转换为小数,然后将它们连接起来。由于一个4字节的无符号值最多需要10位数,因此我们仍然有8位字节块的20位数。你怎么看? – Hemant 2010-04-01 08:10:56

+0

这当然是一个可行的解决方案,正如将其分解成4个每个5位数字的2个字节块。 – 2010-04-01 08:22:45

+0

使用2倍4字节解决方案,您需要注意边界。在高字节中是111 a 1,在低字节中是11,反之亦然?所以你需要使用这个方法总是使用20位数字。 – 2010-04-01 15:29:56

4

效率问题的答案将取决于lot关于8字节块的典型值范围。考虑Unicode的UTF-8和UTF-16。 UTF-8编码主要在西方脚本中编写的文本非常高效,因为这些脚本中的大多数字符范围在0x00到0x7F之间,UTF-8可以存储在单个字节中。但是,对于主要在东方脚本中编写的文本进行编码并不是非常有效; UTF-16或UTF-32是更好的选择。

如果您有关于the various UTFs的阅读,他们可能会激发一个解决方案。从根本上来说,他们通过这样的方式工作,比如允许将很多值直接编码为一个字节,但是然后有一个标志(我认为这是UTF-8的第一个字节)字节不能说明整个故事,并且需要下一个字节(或两个,三个或四个)。起点是UTF-8的一个字节,UTF-16是一个字,但概念是相似的。

现在,你正在使用显着较小范围的值(0-9而不是0-255),显然我不建议试图直接使用UTF,只是概念。例如,说你的大部分价值(直接或按摩)都低于9000,其中不少是低于900万,只有少数价值超过了这个价值。你可以采用UTF方法,并说块(你的8字节值)被分成四位数字段,每个编码块至少有一个段(四位数)。如果第一个段的值(aaaa)介于0000和8999之间(包括),则它是“终端”段  —这就是实际值。但如果它是9aaa,那意味着有第二个分段,你应该看看aaabbbb(bbbb是下一个分段的值)。如果的值介于0000000和8999999(含)之间,则为终端;但如果是9aabbbb,则意味着看aabbbbcccc(cccc是下一个段);等我认为这会给我们这样的:

00000000000000000000-00000000000000008999 -> 4 digits (xxxx) 
00000000000000009000-00000000000008999999 -> 8 digits (9xxxxxxx) 
00000000000009000000-00000000008999999999 -> 12 digits (99xxxxxxxxxx) 
00000000009000000000-00000008999999999999 -> 16 digits (999xxxxxxxxxxxxx) 
00000009000000000000-00008999999999999999 -> 20 digits (9999xxxxxxxxxxxxxxxx) 
00009000000000000000-08999999999999999999 -> 24 digits (99999xxxxxxxxxxxxxxxxxxx) 
09000000000000000000-18446744073709551615 -> 28 digits (999999xxxxxxxxxxxxxxxxxxxxxx) 
Or special case, just use 26 digits for the last one: (999999xxxxxxxxxxxxxxxxxxxx)

有你最好的情况是四位数字和最差的是28或26,这取决于你是否要特殊情况下,在块中的最后segement。比每个块使用20位数字更好(可能)。

现在,这是完全没有关系,可能不如它的效率,但你明白了。反序列化非常容易,而且序列化可能并不困难。

你可以看到为什么我开始评论你的典型值是什么。如果它们通常高于10,000,000,000,000,000,000,则上述内容不是直接编码它们的有效方式。但是,如果您的典型值在高端而不是低端,可以使用类似的技术,方法是在编码之前对该值进行一定程度的按摩。

相关问题