【问题标题】:Compression Algorithm for Encoding Word Lists编码词表的压缩算法
【发布时间】:2010-09-29 03:48:36
【问题描述】:

我正在寻找对算法和/或数据结构的具体建议或参考,以将单词列表编码为有效的拼写检查字典。该方案的目标将导致原始单词列表到编码形式的非常高的压缩比。我对编码字典的唯一输出要求是,可以以相对有效的方式针对原始单词列表测试任何建议的目标单词是否存在。例如,应用程序可能希望对照 100,000 个单词的字典检查 10,000 个单词。 不是编码字典形式能够[轻松]转换回原始单词列表形式的要求 - 二进制是/否结果就是全部根据结果​​字典测试的每个单词都需要。

我假设编码方案为了提高压缩率,将利用给定语言中的已知结构,例如单数和复数形式、所有格形式、缩写等。我对主要编码英语单词特别感兴趣,但是需要明确的是,该方案必须能够对任何和所有 ASCII 文本“单词”进行编码。

我想到的你可以假设的特定应用程序是嵌入式设备,其中非易失性存储空间非常宝贵,而字典将是一个随机访问的只读内存区域。

EDIT:总结一下字典的要求:

  • 零误报
  • 零假阴性
  • 非常高的压缩比
  • 无需解压

【问题讨论】:

    标签: algorithm data-structures dictionary


    【解决方案1】:

    我认为你最好的选择是Compressed Suffix Tree / Compressed Suffix Array。您可以在上述链接中找到大量信息。这是一个正在进行的研究领域,确实非常有趣。

    【讨论】:

      【解决方案2】:

      对于纯压缩,Maximum Compression 网站提供了一些 4 MB 英文单词表的结果,最好的程序将其压缩到 400 KB 左右。用于文本/单词压缩的其他一些压缩资源是 Hutter Prize pageLarge Text Compression Benchmark

      【讨论】:

        【解决方案3】:

        您可以通过将单词存储为 7 位格式的连续后缀来获得 30% 以上的压缩率。我不确定这叫什么,但它可以非常有效地转换为树结构。

        例如: a+n+d+s|an+d+y|and+es+roid

        是 26 个字符,相比之下:

        一个 一个 广告 作为 和 任何 安第斯山脉 安卓

        这是 33。

        考虑到存储为 7 位内容的 12.5% 压缩率,总压缩率约为 31%。当然,压缩比取决于单词列表的大小和内容。

        将其转换为 26 根树结构可能会导致查找速度比纯文本子字符串与平面文件的比较快。

        想一想,如果您只使用 26 个字符加上两个作为分隔符,您可以在 5 位中完成所有操作,这本身就是 37.5% 的压缩率,使上述示例的压缩率超过 50%率。

        【讨论】:

        • 您甚至可以使用特殊字符来选择下一个后缀:a+n!+d+s|d!+y|es+roid - 使其包含 21 个字符。或者你总是先写下一个后缀(19 个字符)。然后,您可以为全新的后缀使用换行符。
        【解决方案4】:

        Knuth 在The Art of Computer Programming vol. 3 中提到了"Patricia trie"。我从未将它用于任何实际工作,但也许这会有所帮助。

        编辑:您的 RAM 限制是什么?如果您的 RAM 比可用的 ROM 多得多,那么 ROM 中的数据压缩(需要解压缩到 RAM)可能是正确的方法。我想如果您有中等但不是大量的 RAM,从技术上讲,您还可以将数据结构的一部分作为压缩 blob 存储在内存中,并使用最近最少使用的缓存来保留其中的几个,然后动态解压缩适当的当 blob 不在缓存中时。

        【讨论】:

        • 我的假设是 RAM 与编码字典的大小相比是有限的,并且要求将块解压缩到 RAM 中以针对字典进行测试可能在计算上并不实用。虽然携带基于 RAM 的状态是可行的,但单词查找需要“就地”和只读发生。谢谢
        【解决方案5】:

        我建议使用填充后缀树。对单词表的良好压缩,以及出色的查找时间。

        http://en.wikipedia.org/wiki/Suffix_tree

        【讨论】:

          【解决方案6】:

          参见麦克罗伊的"Development of a Spelling List"his pubs page。关于小型计算机上的拼写检查的经典旧论文,这些约束与您列出的约束非常吻合。词缀剥离和两种不同压缩方法的详细分析:布隆过滤器和相关方案 Huffman-coding a sparse bitset;我可能会优先使用 Bloom 过滤器,而不是他选择的方法,这种方法会以显着的速度成本挤出更多的 kB。 (Programming Pearls 有一个关于这篇论文的简短章节。)

          另请参阅用于在全文搜索系统中存储词典的方法,例如Introduction to Information Retrieval。与上述方法不同,这没有误报。

          【讨论】:

          • 特别感谢 McIlroy 的参考,这是一个非常好的起点。
          【解决方案7】:

          我不是这方面的专家,但prefix tree 不是对此的标准解决方案吗?它只存储单词的公共前缀一次。

          【讨论】:

            【解决方案8】:

            总结一下:

            • 零误报
            • 零假阴性
            • 高压缩比
            • 无需逆向(即无需解压缩)

            我本来打算推荐 Bloom 过滤器,但这些过滤器的误报率非零。

            相反,Programming Pearls 谈到了一组类似的要求(/usr/share/dict/words in 41K)。

            这采用了词干收缩的方法: 例如:sent 是根目录,因此可以添加前置和后置修复:

            • 现在
            • 代表
            • 表示
            • 虚假陈述

            【讨论】:

            • 词缀剥离会引入误报。不过,我在这里没有看到任何“零误报”要求——拼写检查本质上是不精确的。
            • 拼写检查,按照定义,是非常精确的。该定义根本不包括上下文。
            • 这是不精确的,因为人类语言是开放式的。杰夫可能确实有字典查找的精确问题,而不是拼写检查的不精确问题(我从他的问题陈述中不确定)——但如果是拼写检查,那只是有多少错误以及错误类型的问题。
            【解决方案9】:

            布隆过滤器(http://en.wikipedia.org/wiki/Bloom_filterhttp://www.coolsnap.net/kevin/?p=13)是一种数据结构,用于在某些拼写检查器中非常紧凑地存储字典中的单词。但是,存在误报的风险。

            【讨论】:

              猜你喜欢
              • 2018-10-29
              • 1970-01-01
              • 2010-09-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-11-30
              • 1970-01-01
              相关资源
              最近更新 更多