【问题标题】:Binary Array Compression in CC中的二进制数组压缩
【发布时间】:2010-08-22 13:21:48
【问题描述】:

我在c中有二进制数组,我想压缩数组,请建议我压缩二进制数组的算法。我使用了 Lempel-Ziv-Welch (LZW) 算法,但它不适合我,因为我的数据中没有重复。

【问题讨论】:

  • 如果没有重复,则不能压缩。
  • 重复的机会非常小,以至于LZW失败了。
  • 是什么让你如此确定没有重复?不管你用什么窗户,都没有图案?
  • 删除了 C++ 标签,因为问题标题指定了 C。
  • 我在c中有自己的函数,在数组中生成二进制数据,数组的大小太大,我想压缩和解压缩。

标签: c algorithm compression data-compression


【解决方案1】:

为什么不直接使用libzdeflate?作为额外的奖励,几乎所有现有平台都可以使用 libz。

还是更新的LZMA?它在二进制数据压缩方面胜过bzip2

【讨论】:

  • @Sergius,您的数据中有重复吗?还是您的数据有某种模式?
【解决方案2】:

您可能没有重复,但数据中仍然可能存在可以利用的模式。但是,这需要对数据有更多的了解,而不是没有重复。

如果您的数据实际上(或几乎)随机分布,那么压缩它将会遇到 Pidgin Hole 问题。这表明如果您只有 X 个洋泾浜和 Y 个孔可以放入它们,并且 X > Y,那么您就没有足够的空间。在压缩中,这意味着您无法利用不存储一些 pidgin 的能力,这些 pidgin 是一个已经在一个洞中的同卵双胞胎,而只需给解压缩算法留下注释以克隆该 pidgin。在霍夫曼编码中,所有的洋泾浜都是洋泾浜库中洋泾浜的克隆。在其他几种压缩方案中,一些 pidgins 可能是由其他 pidgins 组成的巨型 pidgins。

【讨论】:

  • 我不明白你所说的数据模式是什么意思,实际上我有来自其他来源的数据。
  • @Arman:如果通过检查初始数据块,您能够以比随机概率更好的方式预测下一个可能的数据块,那么您就有一个可以被压缩算法利用的模式(可能是您必须发明的新产品)。极端情况下,这可能是发送伪随机数生成器的代码,它是种子而不是输出流,但不太极端的情况是发送一大块数据,后跟一个符号,告诉你下一个块是否是包含在行内,或者是 Y 次猜测中的 X 次。
  • @Arman:这只是对重复数据压缩利用的想法的概括。因为你使用了下一个数据完全是前一个数据的想法,而在我刚才谈到的下一个数据将是前一个数据的一些函数,而不是前一个数据。
【解决方案3】:

您可以轻松地将空间切成两半!

由于您的二进制数据没有重复,您唯一的选择是 [0, 1]、[1, 0]。任何更多都会重复零或一。因此,您可以只用 0 表示第一个集合,用 1 表示第二个集合。编码看起来像这样......

encode [0, 1] = 0
encode [1, 0] = 1

解码将是......

decode 0 = [0, 1]
decode 1 = [1, 0]

抱歉,haskell 语法在这种情况下更具可读性。这会将您的两个元素数组变成一个元素数组,并且可以存储在一半的空间中!魔法。

编辑:这忽略了 [0] 和 [1] 的简单情况。如果需要处理这些(尽管您不应该真正压缩 1 位),则不可能获得比 100% 更好的压缩率。

【讨论】:

  • 如果我有 [1, 1] 实际数据,那么在解码结束时它将是 [1, 0, 1, 0]。
  • 我最多有四种可能性 [1, 0], [0, 1], [1, 1], [0, 0]。
  • 你不能有 [1, 1]。规则规定没有重复。如果你有 [1, 1],你有一个重复的 1。
【解决方案4】:

如果您有二进制数据,您很可能会将它们视为char[]。在您的问题和评论中,您声明(几乎)没有重复,这只有在您的数据项不超过 256 个 (char) 时才有可能。

但我猜你有更多的数据,所以压缩是可能的。如果您的数据项的频率分布不均匀,您可能会通过简单的Huffman coding 获得一些运气。

为了向您提供更准确的建议,我们需要有关您要压缩的数据类型的更多详细信息。

【讨论】:

  • 我有 unsigned char[] 我在其中填充了数据,数组的大小是 1.66 KB,我想在 4 秒内将数组传输到串口上,所以我想压缩数据。
  • 然后获取这些数据并通过一些流行的压缩库运行它(尝试 zlib 作为开始),看看哪个性能最好。仅仅因为你没有在数据中看到模式并不意味着它不能用某种算法压缩..
【解决方案5】:

或者:您的二进制数据表示某些值。您可以减少所有值的位数。您需要知道可能的范围并按位写入和读取数据。例如,如果您将值存储在只需要几位的 uint32 中,这可能会节省大量空间。

【讨论】:

  • 我已经填充了与值范围相关的所有位,没有空间可以减少内存大小。
  • @Arman:好的,所以你的数据很密集,熵低且没有重复。你可以做一个霍夫曼编码来看看压缩是否有用。
【解决方案6】:

压缩不是魔术。如果您的数据是完全随机的,则没有可用的压缩算法可以使其更小。

大多数数据不是完全随机的,但您需要自行发现表达数据的最佳方式,以便检测出模式。图像和声音很常见,以至于已经开发了标准算法,但如果不了解更多细节,就无法对您的具体问题进行更多说明。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多