3

多くの文字列を TStringList に格納するためのアプリケーションがあります。文字列は互いにほとんど同じであり、それらをその場で圧縮することができると思います。つまり、特定の文字列を、一意のテキストフラグメントと以前に保存されたフラグメントへの参照の混合物として保存します。完全修飾パスとファイル名のリストなどの StringList は、大幅に圧縮できるはずです。

これを実装するTStringlistの子孫を知っている人はいますか?

各アクセスの前に文字列リスト全体を解凍し、後で再圧縮することでこれを実装できますが、不必要に遅くなります。私は、インクリメンタル操作とランダムな「シーク」と読み取りに効率的なものを求めています。

ティア・ロス

4

4 に答える 4

2

これについて自由に利用できる実装はないと思います (商用コードで少なくとも 3 つの同様の構造を作成しましたが、とにかく私が知っているわけではありません)。

アイテムを順番に追加することについてマルセロが行った発言は非常に関連性があります。おそらく、追加時にデータを圧縮したいと思うでしょう-追加されているものとすでに類似しているエントリにすばやくアクセスできると、セット全体で「最適なエントリ」(類似性圧縮に必要)を検索します。

あなたが読みたいと思うかもしれないもう1つのことは、「ロープ」です。これは、私がマルコ・カントゥに少し前に提案した文字列とは概念的に異なるタイプです。「より糸」ごとに次のポインターを犠牲にして (より適切な単語がないため)、重複データを保持せずに文字列の一部を連結できます。主な問題は、元の文字列を表す新しい「ロープ」に結合できるパーツを取得する方法です。この問題が解決されれば、いつでもデータを文字列として再構築できますが、ストレージはコンパクトに保たれます。

「ロープ」ルートに行きたくない場合は、「プレフィックスリダクション」と呼ばれるものを試すこともできます。これは単純な形式の圧縮です-各文字列を前の文字列のインデックスと文字数で始めるだけですこれは、新しい文字列のプレフィックスとして扱われるべきです。これを再帰しすぎると、アクセス速度が大幅に低下することに注意してください。1 つの単純な実装では、mod 16プレフィックスの削減が開始されたエントリを確立するために、インデックスに対して実行しました。これにより、平均で約 40% のメモリが節約されました (この数値はもちろん完全にデータに依存します)。

于 2010-09-13T13:59:52.660 に答える
0

リストから一般的な柔軟性 (削除操作を含む) を期待していると思います。この場合、すぐに使用できるソリューションについてはわかりませんが、次の 2 つのアプローチのいずれかをお勧めします。

  • 文字列を単語に分割し、単語を参照してインデックスのリストを内部的に保存するために、分離された拡張辞書を保持します

  • Delphi で利用可能な zlib ストリームに関連するものを実装しますが、たとえば 10 ~ 100 個の文字列を含むことができるブロックによって操作します。この場合、完全なブロックを再圧縮/圧縮する必要がありますが、支払う「価格」は低くなります。

于 2010-07-13T14:47:59.233 に答える
0

メモリ内の TStrings アイテムを圧縮する必要はないと思います。非常に効率が悪いからです。Zlib ユニットの TStream 実装を確認することをお勧めします。読み込み時に通常のストリームを TDecompressionStream にラップし、保存時に TCompressionStream にラップするだけです (gzip ヘッダーを出力することもできます)。ヒント: LoadFromFile/SaveToFile の代わりに LoadFromStream/SaveToStream をオーバーライドする必要があります。

于 2010-11-13T02:37:09.287 に答える
0

Judy 配列を Delphi または COM API でラップすることもできます。JudySL 型はうまく機能し、かなり単純なインターフェイスを備えています。

EDIT:一意の文字列を保存していて、それらを辞書順に保存したい(または喜んで保存したい)と仮定します。これらの制約が受け入れられない場合、Judy 配列は適していません。文字列をソートしないと、圧縮システムが影響を受けることに注意してください。

于 2010-07-13T13:07:07.560 に答える