【问题标题】:Compress many numbers into a string将多个数字压缩成一个字符串
【发布时间】:2014-06-22 08:06:13
【问题描述】:

我想知道是否有办法将 20 个左右的大数字 (~10^8) 压缩成一个合理长度的字符串。例如,如果将数字存储为十六进制并连接起来,则它至少有 160 个字符长。我想知道是否有一种聪明的方法可以压缩数字并将它们取出。我正在考虑将序列 0-9 作为参考,并让输入字符串的一部分为

有没有更好的选择?

谢谢

【问题讨论】:

  • 加密和压缩是两个不同的东西,你问的是什么? (如果是压缩,答案是“一般来说这是不可能的”。)
  • @OliCharlesworth 我应该问的是压缩而不是加密。为什么压缩通常是不可能的?
  • 因为鸽巢原理
  • 这里的“字符串”是什么?它是一个可打印字符序列,还是一个字节序列?单个字符允许使用哪些值?一般的解决方案是在 Basis(number_of_different_values_for_each_character) 中表示您的输入值。

标签: algorithm compression


【解决方案1】:

如果这些大数字的字节大小相同,并且您总是知道这些数字的计数,那么有一种简单的方法可以做到这一点。您只需拥有一个字节数组,而不是将它们作为整数读出,而是将它们作为字符读出。您是想混淆您的价值观还是只是将它们打包以便轻松转移?

【讨论】:

  • 那么我提供的理论就可以很好地工作,并且大小会更小,然后将数字视为字符串。
  • 是为了帮助转移,但我只是想把字符串的长度剪掉。
【解决方案2】:

当我将大量值压缩为一个可逆的String 时,我通常使用base 64 转换。这确实可以从String 中截断相当多的长度,但请注意,它在表示它时可能会占用同样多的内存。

示例

这个十进制数:

10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

在 Base 64 中如下:

Yki8xQRRVqd403ldXJUT8Ungkh/A3Th2TMtNlpwLPYVgct2eE8MAn0bs4o/fv1bmo4oUNQa/9WtZ8gRE7IG+UHX+LniaQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

为什么你不能做到这一点太极端了

想一想。假设您有多个长度10。并且您想用5 字符表示该数字,因此使用50% 速率压缩方案。首先,我们计算出您可以用10 数字表示多少个可能的数字.. 即..

2^10 = 1024

好的,没关系。 5 digits可以表达多少个数字:

2^5 = 32

因此,您只能显示带有5 位的32 个不同数字,而您可以使用10 位显示1024 数字。为了使压缩工作,压缩值和提取值之间需要有一些映射。让我们尝试实现这种映射..

Normal - Compressed
0        0
1        1
2        2
..       ...
31       31
32       ??
33       ??
34       ??
...      ... 
1023     ??

扩展值可以表示的大多数数字都没有映射。

这被称为Pigeonhole Principle,在本例中,n 的值大于m 的值,因此我们需要将压缩值中的值映射到多个正常值,这使得事情异常复杂。 (感谢 Oli 提醒我)

【讨论】:

  • 感谢您的解释。我的主要目的不是减少内存使用,而是减少长度。
  • 那么base64 可能是您的好方法。它减少了很多,您可以在原始数字和base64 编码版本之间进行映射。
  • 我可能做错了:我使用motobit.com/util/base64-decoder-encoder.asp 对您的输入进行编码,但结果是 MTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw...
  • 不是从String 转换它,而是将其解释为数字:convertxy.com/index.php/numberbases
  • 对于某些输入数据,可以选择处理循环的最小化尝试。然后base64那个试试。看我的回答。
【解决方案3】:

您需要更详细地描述“字符串”和“~10^8”的含义。您的“字符串”可以包含任何字节序列吗?还是仅限于可能字节的子集?如果是这样,它究竟是如何限制的?你的“大数”有什么限制?它们代表什么?

最多 108 的数字可以用 27 位表示。如果允许任何字节序列,其中 20 个将是 540 位,可以存储在 68 字节的字符串中。如果字符串的内容是有限的,它将占用更多位。如果您的数字范围更大,则需要更多位。

【讨论】:

    【解决方案4】:

    这当然很大程度上取决于您的输入。但是以这种方式构建(非常)紧凑的表示是可能的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      • 1970-01-01
      • 2020-01-29
      相关资源
      最近更新 更多