如何压缩一个非常大的数字(通过用ascii值替换文本文件中的字符获得的大数字)?

时间:2013-10-21 20:38:09

标签: algorithm math compression

一般来说,我不是在谈论特定的语言。我试图通过用ascii值替换每个字符来找到压缩文本文件的方法,以便结果是一个大数字。由于可以用较少的字符以数学方式表示大数字,因此可以压缩文件。

4 个答案:

答案 0 :(得分:2)

嗯,是的,一个大数字可以用数学表达,并可能节省一些空间。因此,如果将每个字符转换为ASCII值,则每个字符从单个字节扩展为1,2或3个字节。也就是说,'A'变为'65'。 'z'变为'122'。对于大多数文本,请将扩展比率设置为2.5到1之间。

所以拿一个1000字节的文本文件。将所有字符转换为相应的ASCII值。您现在拥有2,500位数字。在某些情况下,该数字可以少于1,000个字符表示。但这些都是特例。通常,您不会通过首先将数据转换为原始大小的2.5倍来压缩数据。

但如果你想尝试,那就够了。

Open input file as binary
Open output file as text

for each byte in input
    cast the byte to an int and output its string representation

在C中,最后一个语句如下:

printf("%d", (int)c);

假设c是您从输入文件中读取的字节。

您现在有一个文件,其中所有字符都是0-9。例如:

Hello, world

变为

72,101,108,108,111,44,32,119,111,114,108,100,

除了逗号不在那里:

721011081081114432119111114108100

欢迎您尝试使用您的技术提出压缩方案。我认为你会发现它适用于可能输入的一小部分,当它确实有效时,需要很长时间才能找到合适的数学公式。通过下载维基百科的全文并尝试压缩单篇文章来测试是很容易的。当你认为你有一些运作良好的东西时,我当然有兴趣测试它。

答案 1 :(得分:1)

首先,我们陈述一些假设:

  1. 您希望进行“无损”压缩,也就是说,您希望能够在压缩后恢复文件。 (否则,我们可以用单个位“代表”每个文件1)
  2. 文件中的文本假定为ASCII,这只是一个单字节字符的序列(实际上我们使用的编码并不重要,但为了简化操作)
  3. 任何可能的角色同样可能出现在文本中(即,我们正在谈论的宇宙是所有可能的文件)
  4. 每个单字节字符可以取值0-255(已知为扩展ASCII)
  5. 第一个设定答案:将文字转换为数字没有任何优势,因为它已经是一个数字

    使用这个假设,任何文件实际上已经是一个很大的数字,更具体地说,是大二进制数。如果文件具有长度n个字符,则它是具有8*n位的二进制数。因此,没有“将其转换为大量”的优势,因为它实际上已经是一个数字。

    我希望你对这个概念很清楚。

    现在我们继续“将文本转换为数字以压缩它”实际可行的内容

    第二个设置答案:节省12.5%的空间,假设文件中只有前128个字符

    如果您正在查看文本的小部分,即当我们仅使用ASCII的前128个字符时(即,违反),您声称“因为大数字可以用更少的字符以数学方式表达”似乎是正确的假设4),这是更常用的字符集。在这种情况下,我们实际上只能将每个字符表示为7位二进制数而不是8位。通过这样做,我们已经节省了12.5%的空间。

    现在,更有趣的一个。

    第三个设定答案:有一个叫做霍夫曼压缩的东西

    Huffman Compression通过骚扰字符的自然分布,通过用较少的位表示每个字符来节省空间。在自然文件中,某些字符出现的次数比其他字符多(即违反假设3),如果我们使用较短的位序列来表示这些字符,以使用更多位表示其他不常用字符为代价,我们实际上可以节省空间。当文件仅包含多次重复的单个字符时,哈夫曼压缩对ASCII的最佳性能将达到87.5%。

答案 2 :(得分:0)

您可以尝试使用范围编码器。它可以使用一小部分。

答案 3 :(得分:0)

这里有一些很好的答案,但我想补充几点。 justhalf 有我认为最好的观点:

让我们看看如何将文本转换为数字:

1)你有一组ASCII字节。对于每一个,您编写一个0到255之间的数字。 每个整数占用多少空间? - 与ASCII完全相同的空间: 这不是巧合,ASCII只是一组用于解释0-255数字含义的规则 首先。

2)您将每个字符换成一个数字,然后将它们链接起来,然后存储该数字。这似乎很好,也许 如果你有一个规则用'1'交换'a':'aaaaaa'将映射到111111,它可以存储在一个字节中! 但是'k'='11'和'aa'= 11'怎么样? (这似乎打破了Jim Mischel的回应?)

但是,这里存在一个更严重的问题:您在一组字节中存储长度为n的字符串 256 ^ n个可能的值。这是:您可能需要在某些时候使用所有这些表示。

现在,您可以创建从这些值到数字的一对一映射。仍然会完全一样 可能数量的数量:256 ^ n(n个字符中的每一个都有2 ^ 8种可能性)。而最小的方式 代表256 ^ n的可能性是使用log_2(256 ^ n)位。这是8n。这应该是熟悉的。它与长度为8的n个字节一样,就像我们以前一样!

你遇到的问题是,在不知道发行版的情况下(每封信的可能性有多大) 你的输入字母,你可能会出现每个角色同样可能的情况 因此,通过使用比其他字符串更小的表示来编码某些字符串没有任何好处。

然而,正如其他人所提到的,如果您知道输入的分布函数。说你的文字是 一串DNA,你只有四个字母:'G,T,A,C'。每个字母只需要两位,您可以将输入压缩四次!

如需更多阅读,请在Information Theory上了解Wiki。