私はcにバイナリ配列を持っています、私は配列を圧縮したいです、親切にバイナリ配列を圧縮するアルゴリズムを提案してください。Lempel–Ziv–Welch(LZW)アルゴリズムを使用しましたが、データに繰り返しがないため、これは適していません。
6 に答える
繰り返しはないかもしれませんが、それでもデータに利用できるパターンが存在する可能性があります。ただし、これには、繰り返しがないことよりも、データについて詳しく知る必要があります。
データが実際に(またはほぼ)ランダムに分散されている場合、データを圧縮するとピジンホールの問題が発生します。これは、X個のピジンとY個の穴だけがあり、X> Yの場合、十分なスペースがないことを示しています。圧縮では、これは、すでに穴にあるものと同一の双子であるいくつかのピジンを保存しない機能を利用できず、そのピジンを複製するための解凍アルゴリズムにメモを残すことを意味します。ハフマンコーディングでは、すべてのピジンはピジンライブラリ内のピジンのクローンです。他のいくつかの圧縮スキームでは、一部のピジンは他のピジンで構成されたメガピジンである場合があります。
簡単に半分にできます!
バイナリデータには繰り返しがないため、オプションは[0、1]、[1、0]のみです。それ以上のものは、0または1のいずれかを繰り返します。したがって、最初のセットを0で表し、2番目のセットを1で表すことができます。エンコーディングは次のようになります...
encode [0, 1] = 0
encode [1, 0] = 1
そして、デコードは...
decode 0 = [0, 1]
decode 1 = [1, 0]
haskellの構文については申し訳ありませんが、この場合ははるかに読みやすくなっています。これにより、2つの要素の配列が1つの要素の配列に変わり、半分のスペースに格納できます。魔法。
編集:これは、[0]と[1]の些細なケースを無視します。それらを処理する必要がある場合(実際には1ビットを圧縮するべきではありませんが)、100%よりも優れた圧縮率を得るのは不可能です。
バイナリデータがある場合は、それらをのようなものとして扱う可能性がありますchar[]
。あなたの質問とコメントの中で、あなたは(ほとんど)繰り返しがないことを述べています。これは、256()を超えるchar
データ項目がない場合にのみ可能です。
しかし、私はあなたがより多くのデータを持っていると思うので、圧縮は可能です。データ項目の頻度が均等に分散されていない場合は、単純なハフマンコーディングで運が良かったかもしれません。
より正確なアドバイスを提供するには、圧縮するデータの種類に関する詳細が必要です。
または、バイナリデータが特定の値を表しています。すべての値のビット数を減らすことができます。可能な範囲を知り、データをビット単位で読み書きする必要があります。たとえば、数ビットしか必要としない値をuint32に格納する場合、これにより多くのスペースを節約できる可能性があります。
圧縮は魔法ではありません。データが完全にランダムである場合、データを小さくすることができる圧縮アルゴリズムはありません。
ほとんどのデータは完全にランダムではありませんが、パターンを検出できるようにデータを表現する最適な方法を見つけるのはあなた次第です。画像と音声は十分に一般的であるため、標準のアルゴリズムが開発されていますが、詳細を取得しない限り、特定の問題についてこれ以上語ることはできません。