我有数百万个街道名称的列表,并希望使用压缩算法对其进行压缩。我不确定哪种算法最适合。大多数街道名称中都有共同的子字符串,例如“street”、“way”、...
所有街道名称的集合是固定的,不会动态变化。
起初我在考虑霍夫曼编码,但它只编码单个字母,所以它不会提供很好的性能。所以我想生成一个 trie 并计算最常见的子字符串。然后我可以有某种代码来遍历这个 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%
非常感谢您的回答