“减少存储空间”数字的算法/数字格式

时间:2014-01-26 17:48:21

标签: java algorithm math storage discrete-mathematics

我有非常严重的问题需要解决。我有一个75000字的清单。每个单词都分配有一个数字,便于识别。第一个单词分配0,最后一个单词分配75000.现在,我有一个句子列表。让我们以一句话为例。

I have big dog

当您使用指定的数字表示时,它会变为20 123 2332 3434。这只是意味着单词 I 出现在我们列表中的第20个单词,单词 作为123单词出现在我们的列表中,单词 big 显示为2332字,依此类推。

就像这样,我有超过20亿个句子,我需要保存/写出他们的数字表示。我们觉得在20亿条记录中保存像20 123 2332 3434这样的长数字会占用很大的空间。相反,如果我们可以使用像F3x G6e rRr这样的较短数字系统来表示它们,那么它将节省我们的存储空间。

我怎样才能做到这一点?可能正在使用十六进制数字?我使用了this转换器,似乎没有太大区别,因为十六进制数 123456 1e240 数字 75000 十六进制 124f8 等等;似乎字符的数量是相同的,所以我不确定它是否会节省任何空间。

请告诉我你完成这项任务的建议。我将用Java编写这个函数。

2 个答案:

答案 0 :(得分:4)

十进制数字为每个字节提供10种可能性。十六进制数字为您提供16.如果您可以使用所有可能的位模式,则每个字节将有256种可能性,相当于在一个空格中存储两个十六进制数字。根据您存储和检索数据的方式,您可能会发现http://en.wikipedia.org/wiki/Base64编码可以避免损坏,例如:您不能存储零字节或其他位模式,例如高位设置的位模式。

有更复杂压缩的可能性。人们可以简单地使用标准压缩器,例如java中由java.util.Zip包提供的压缩器,或其他语言中的等效压缩器。另一个 - 如果你知道常见的单词是多少,那就是简单地对单词进行排序,使常用单词的数字较少,因此数字较短。您也可以查找http://en.wikipedia.org/wiki/Huffman_coding。这样可以避免在数字之间留出空格,并且还可以缩短短数字序列。

答案 1 :(得分:1)

实现字符串的二进制表示。第一个16/32位表示字符串 n 的长度,然后按 n 17位整数表示数组中75000个字的索引。数字17大致是75000的基数2的对数。所以你的例子将成为(假设字长为16位):

 0000 0000 0000 0100   0 0000 0000 0001 0100   0 0000 0000 0111 1011   
|                  4 |                    20 |                   123 | 
                       0 0000 1001 0001 1100   0 0000 1101 0110 1010 
                     |                  2332 |                  3434 |

然后,您可以使用例如Robert Sedgewick的BinaryIn and BinaryOut classes将该位流转换为二进制文件。请注意,上面的字符串现在只需要编码21个字节。

如果您事先知道单词的分布,则可以使用Huffman压缩来压缩二进制流。如果分布倾向于一小部分单词,这可以节省大量空间。