【问题标题】:Java algorithm to Compress small numeric numberJava算法压缩小数字
【发布时间】:2012-06-26 14:19:07
【问题描述】:

我需要将 20-40 字符大小的数字压缩为 6 字符大小的数字。到目前为止,我已经尝试了 Huffman 和一些 Zip 算法,但没有得到想要的结果。

有人可以为这项工作在 Java 中提供任何其他算法/API 吗?

例子:

Input: 98765432101234567890
Desired Output: 123456

请注意:我并不是说给定输入的输出必须为 12345。我只是说如果我指定 20 字节的数字,它应该被压缩成 6 字节的数字。

用法:压缩后的数字将输入设备(最多只能占用 6 个数字字符)。设备会将号码解码为原始号码。

假设/限制:

  1. 如果需要,客户端和设备(服务器)可以共享一些公共的 编码/解码数字所需的属性。

  2. 只能向设备发出一个请求,即应提供所有数据 在一个请求中,没有大块的小数据包

谢谢。

【问题讨论】:

  • 如果您以二进制形式(原始数据)表示数字,则可以执行此操作。但即便如此,您仍需要 9 个字节来存储。
  • 你所要求的是不可能的。
  • 你需要实际压缩数字吗?还是您实际上需要的是哈希?
  • 那你为什么不把数字分成6个字节的块呢?也许通过某种编码告诉设备有多少块。做你想做的唯一方法是如果有问题的数字共享某种属性,例如,如果它们都可以被 100 整除,那么你可以不存储最后 2 位数字。但是对于通用数字,您无法将单个 # 压缩为较小的 # 字节,至少不能,除非您有很多这样的数字要存储在单个 blob 中
  • 您指定 Java,并说您有 6 个chars。由于 Java char 是 16 位,因此提供了 96 位,足以对所有不超过 28 个十进制数字的数字进行编码。如果您需要处理更大的数字,并且对合法数字没有严格的限制,那根本不可能。

标签: java algorithm


【解决方案1】:

假设任何数字组合都是合法输入,这将是你能得到的最好的结果:

final String s = "98765432101234567890";
for (byte b : new BigInteger('0'+s).toByteArray()) 
  System.out.format("%02x ", b & 0xff);

打印

05 5a a5 4d 36 e2 0c 6a d2

理论上,以二进制形式存储数字是最有效的方式,因为每个位组合都是一个不同的合法值。

只有在您的输入中有更多冗余时,您才可能有其他选择,即对合法数字组合有一些限制。

【讨论】:

  • Marko:感谢您的宝贵时间,但尝试为相同的输入打印不带 .length 的输出,您会注意到一个奇怪的行为(相同输入的输出始终不同)。
  • 如果“输出”是指 Java 数组的默认 toString 实现(返回从内存中的物理地址生成的 hashCode),那么是的,每次输出都不同 - - 和你无关。
【解决方案2】:

按照您指定的方式,这是不可能的。 20 位数字比 6 位数字多,因此如果将 20 位数字映射到仅 6 位数字,则必须将一些 20 位数字映射到相同的 6 位数字。如果您知道并非所有数字都有效甚至具有相同的可能性,则可以将其用于压缩,否则这是不可能的。

虽然从 20 位数字到 6 位数字的可逆(双射)映射是不可能的,但仍然可以将长数字映射到较短的输出。这通过减少输出需要是数字的要求来起作用。唯一重要的考虑是输出序列需要与输入具有相同数量的可能性。这是一个例子:

  • 有 10^20 个可能的 20 位数字
  • 如果您使用长度为 x 的完整 8 位 ASCII(256 个字符)序列,您将有 256^x 个可能的输出。如果你为 x 解决这个问题,你会注意到 256^9 > 10^20 所以 9 个 ASCII 字符足以编码 20^10 个可能的数字输入。

Marko 对同一问题的回答将告诉您如何将数字转换为可用作输入的字节表示。但请注意,此输入不会是数字,可能包含许多奇怪的符号。

【讨论】:

  • 请注意,OP 已经尝试过 Huffman 等。这会产生二进制输出。
  • @MarkoTopolnik:是的,同意。很可能他想要一些二进制格式,否则这是不可能的。但是,我还想指出,从要求的描述中并不清楚这一点。所以我绝不是暗示你的答案是错误的。
猜你喜欢
  • 1970-01-01
  • 2013-11-09
  • 1970-01-01
  • 2013-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-07
  • 1970-01-01
相关资源
最近更新 更多