【问题标题】:String to string compression algorithm?字符串到字符串压缩算法?
【发布时间】:2012-09-02 00:14:29
【问题描述】:

我正在寻找一种可以将某个字符串压缩为另一个字符串(即没有“\0”或特殊控制字符)的算法,但我在互联网上找不到任何东西。有这样的算法吗?它不必特别高效,只要一些基本的东西即可。

【问题讨论】:

  • 任何压缩算法都可以做到这一点。
  • @MAKKAM,这并不相关。他想要一种针对特定类型字符串(短字符串)的算法,而我需要一些通用的。
  • @static_rtti,我正在寻找一种可以输出可以复制和粘贴的字符串的压缩算法。我认为大多数压缩算法都会输出带有\0 字符的二进制数据。

标签: string algorithm compression


【解决方案1】:

简单:

$ echo "Hello world" | gzip -c | base64
H4sIALnHeU4AA/NIzcnJVyjPL8pJ4QIA1eA5twwAAAA=

$ echo "H4sIALnHeU4AA/NIzcnJVyjPL8pJ4QIA1eA5twwAAAA=" | base64 -d | gzip -dc
Hello world

注意:看起来没有压缩,但是对于更大的数据压缩率会更好:-)

【讨论】:

  • base64 在 OP 提到的约束下效率不高,有超过 90 个可打印的 ASCII 字符,在扩展 ascii 中甚至更多
  • 建立了原则。你可以替换 Ascii85,或者使用更多可打印字符的其他方案,提问者说,“它不必特别有效”。
  • @harold,是的,可能不是尽可能节省空间,但 OP 说 “它不必特别高效,只是一些基本的东西” - 并且而已! Base64 非常基础、简单且可移植。它可以在多种语言中使用。并且无需为自己实现任何其他东西,无需重新发明轮子。
  • 它必须特别低效吗?好吧,这并没有那么糟糕,但这有点伤害了我的“本来可以更好”的感觉。如果首先没有压缩阶段,那么对我来说只使用 base64 是有意义的,但现在没有那么多了。
  • 我试过了,不得不将--ignore-garbage添加到base64 -d
【解决方案2】:

显然你有一些特定的字符集,你想将它用于原始字符串和压缩字符串。

标准压缩例程(例如gzip)适用于字节字符串。

一个想法是采用现有代码(例如 gzip)并重写它以使用您的字符集 而不是字节。

另一种方法是在字符集中的字符串和任意字节字符串之间构建一对一映射,将原始字符串映射到字节字符串,使用标准压缩实用程序或函数压缩字节字符串,然后映射结果使用您的字符集返回字符串。 (严格来说,您可以使用两种不同的映射。)

构建映射的一种方法是用虚拟字符和特殊的填充字符填充字符集,直到有 2^k 个不同的字符(对于某些 k);那么你的每8个字符对应k个字节(较短的字符串可以用填充字符填充)。

【讨论】:

    【解决方案3】:

    您对“特殊字符”的要求非常严格,除非您可以保证从不使用部分字符(例如“~”)。然后你可以使用这些字符来标记你的压缩:

    ~a->
    ~b -> 的
    ~c -> 和
    ~d -> 和
    ~e -> Sirius Robotics Corporation Ltd.
    等等。

    只需将常用词添加到密码本即可。如上所述,码本可以是固定的,也可以随着要压缩的文本而变化。无论哪种方式,解压端都需要访问正确的密码本才能进行解压。

    【讨论】:

      【解决方案4】:

      据我所知,最流行的压缩算法允许重新使用标准 C 字符串处理例程来处理压缩文本(即,小心避免在压缩字符串中放置任何 0x00 字节,除了结尾-of-compressed-data marker)是simple byte-pair encoding,也称为dual-tile encoding或DTE。 DTE 通常用于压缩视频游戏 ROM 中的文本。

      当 DTE 解压器打印出一个 DTE 压缩的字符串时,它每次从 DTE 压缩的字符串中读取 1 个字节,并打印出 1 个或 2 个字节:

      • 0x01..0xFF 范围内的压缩字节 B:解码器将其用作“字典”的索引,并打印出存储在该索引处的字典中的 1 或 2 个字节。
      • 压缩后的字节 B 为 0x00,这是字符串的结尾 -- 完成。

      典型的 DTE 实现在编码器和解码器中都存储了一个硬连线字典,如下所示:

      • 常用字母的索引——也许整个 ASCII isprint() 范围从 0x20 到 0x7e,换行符 0x0A——代表它们自己。 (压缩字节“a”被解码为单个字母“a”)
      • 从 0xc0 到 0xff 的索引:该字节被解码为 2 个字符:一个空格字符,以及由该字节与 0x80 异或形成的一个字母。 (压缩字节(0x80 xor 'a')被解码为 2 个字符,空格字符和字母 'a')。
      • 任何其他可用索引 (0x7f..0xbf) 存储其他常见的二元组(“th”、“re”等)。

      【讨论】:

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