想要街道名称的压缩算法

时间:2013-03-26 19:29:55

标签: compression huffman-code

我有一个包含数百万街道名称的列表,并希望使用压缩算法对其进行压缩。我不确定哪种算法最适合。大多数街道名称中都有共同的子串,例如“street”,“way”,......

所有街道名称的集合是固定的,不会动态更改。

起初我想的是霍夫曼编码,但这只编码单个字母,所以它不会给出很好的表现。所以我想到生成一个特里并计算最常见的子串。然后我可以使用某种代码来遍历这个trie以便恢复这个词,并使用像霍夫曼编码这样的东西来压缩这些代码。我不确定这是不是让它变得比它需要的更复杂。

有没有人知道在我的情况下有意义的压缩技术?

编辑1

我的用例是:我有一个存储空间有限的手机设备。这款手机需要保存特定国家/地区所有街道的所有街道名称。现在每个街道对象都有一些值,其中街道名称为字符串。这占用了大部分空间,我想尽量减少它。由于名称非常相似,即大多数以“...... street”或“...... way”结尾,我认为可能值得实施针对此场景的特定压缩算法。

简单的gzip带来了约50%的压缩率。我认为应该可以从中获得更多。

编辑2

Ebbe M. Pedersen的解决方案实际上给出了非常好的表现结果。这是一些代码(用C#编写):

    private IndexedItem[] _items;

    public void CompressStrings(string[] strings)
    {
        Array.Sort(strings);
        _items = new IndexedItem[strings.Length];

        string lastString = string.Empty;

        for (int i = 0; i < strings.Length; i++)
        {
            byte j = 0;
            while (lastString.Length > j && lastString[j] == strings[i][j])
            {
                j++;
            }

            _items[i] = new IndexedItem() { Prefix = j, Suffix = strings[i].Substring(j) };

            lastString = strings[i];
        }
    }

    private struct IndexedItem
    {
        public byte Prefix;
        public string Suffix;
    }

压缩后我也通过DeflateStream发送它,导致总压缩率 30%

非常感谢答案

3 个答案:

答案 0 :(得分:2)

根据您的数据集,您可以先订购街道名称,然后将每个街道名称表示为前一个街道名称的子字符串+“不同部分”。

一些类似街道名称的示例:

      How much to copy from previous street name in Hex 
                         | The rest of the street name
Original                 V   V V V            Orig size  New size
Broadwalk                0 Broadwalk             9         10
Broadwater               7 ter                   8          4
Broadwater Access        A  Access              17          8
Broadwater Bluff         B Bluff                16          6
Broadwater Branch        C ranch                17          6
Broadwater Bridge        D idge                 17          5
Broadwater Cemetary      B Cemetary             19          9
Broadwater Creek         C reek                 16          5
Broadwater Point         B Point                16          6
Broadwater Pvt           C vt                   14          3
Broadwaters              A s                    11          2
Broadway                 7 y                     8          2
Broadway And Union       8  And Union           18         11
Broadway Apartments      9 partments            19         10
Broadway Avenue          9 venue                15          6
                                               ---        ---
                                               220         93

您需要处理一系列名称才能进入真实的名称,但如果您制定完全拼写每n条记录的惯例,则可以根据需要对其进行优化。

结合使用每个字母仅使用5-6位,并且可能做一些常见的子串替换,你应该能够用你的bzip来看到50%。

答案 1 :(得分:1)

使用静态字典编码算法会更好。您可以试试我的玩具压缩工具:http://code.google.com/p/comprox。 (comprop组件)

但最好的方法是在将数据传递给通用压缩程序之前对数据进行无损转换,因为您可以更好地理解数据。

答案 2 :(得分:0)

不要使用Huffman,LZ算法最适合这种情况。

我建议您将所有街道名称合并为一个文本文件(仅限街道名称)。每个街道名称应该NULL终止,以帮助拉出单个字符串。压缩此文件。然而,你必须弄清楚如何在移动设备的有限内存中管理它。

另外,请查看SMAZ