何百万もの通りの名前のリストがあり、圧縮アルゴリズムを使用してそれらを圧縮したいと思います。どのアルゴリズムが最適かわかりません。ほとんどのストリート名には、「street」、「way」、...などの一般的なサブストリングが含まれています。
すべてのストリート名のセットは固定されており、動的に変更されることはありません。
最初はハフマン符号化を考えていましたが、それは一文字しか符号化しないので、あまり性能が出ません。そこで、トライを生成して、最も一般的な部分文字列を数えることを考えました。次に、単語を取り戻すためにこのトライをトラバースするためのある種のコードを作成し、ハフマンコーディングなどを使用してこれらのコードを圧縮することができます。これが必要以上に複雑になっていないかどうかはわかりません。
私の場合に意味のある圧縮技術を知っている人はいますか?
編集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%の圧縮が行われます。
答えてくれてありがとう