-1

誰かが数値の圧縮に使用される既存のアルゴリズムに名前を付けることができますか? 数値は整数であり、スペースや小数を含まない完全にランダムです。35637462736423478235687479567456...n

まあ、これまでのところ、私が持っているのはこれだけです。整数をASCIIに変換し、元のサイズの約40%を削減します

function intergerToChar($v)
{
    $buffer="";
    $charsLen=strlen($v);
    for($i = 0; $i <= $charsLen; $i++)
    {     
        $asc=$v[$i];
        if($asc==0){$buffer[]=0;}
        elseif($asc==1){$buffer[]=$v[$i].$v[$i+1].$v[$i+2];$i=$i+2;}
        elseif($asc==2)
        {
            if($v[$i+1]<5){$buffer[]=$v[$i].$v[$i+1].$v[$i+2];$i=$i+2;}
            elseif($v[$i+1]==5 && $v[$i+2]<6){$buffer[]=$v[$i].$v[$i+1].$v[$i+2];$i=$i+2;}
            else{$buffer[]=$v[$i].$v[$i+1];$i++;}       
        }
        else{$buffer[]=$v[$i].$v[$i+1];$i++;}  
    }
    return $buffer;   
}

ところで、PHP が圧縮ツールを構築するためのものではないことは知っています。C/C++ を使用します

更新: これは、上記のコードよりも優れた圧縮結果を持つ別の PHP コードです。1 番目、6 番目、12 番目などの位置の整数の値が 256 未満で、次の 3 つの整数が続く場合、最大 66% 圧縮できます。それらは、前の 3 つの整数よりも 256 以下の値を持ちます。たとえば、134298156286159.... は 66% まで圧縮できます。

function intergerToChar2($v)
{
    $buffer="";
    $charsLen=strlen($v);
    for($i = 0; $i <= $charsLen; $i++)
    {     
        if($v[$i].$v[$i+1].$v[$i+2]<256){$base=$v[$i].$v[$i+1].$v[$i+2];$i=$i+2;}
        else{$base=$v[$i].$v[$i+1];$i=$i+1;}$i=$i+1;

        if($v[$i].$v[$i+1].$v[$i+2]<256){$next=$v[$i].$v[$i+1].$v[$i+2];$i=$i+2;}
        else{$next=$v[$i].$v[$i+1];$i=$i+1;}

        if($next!=="")
        {
            $next=$next-$base;
            if($next<0)$next=255+$next;
        }

        $buffer[]=$base;
        $buffer[]=$next;
    }
    return $buffer;   
}

ちなみに、10 ビット エンコーディングまたは 40 ビット エンコーディングは、base_convert() またはhttp://php.net/manual/en/ref.bc.phpページの 4 番目のコメントを使用して簡単に実行できます。これは、常に約 58.6% の圧縮を示しています。

4

1 に答える 1

4

数字がランダムである場合、情報理論上の制限 (log 2 10 ビット/数字) を超えてシーケンスを圧縮することはできません。(実際には、文字列の正確な長さが固定されていない限り、それよりもわずかに長くなります。) 数字を (非常に長い) 2 進数として表すことで、その制限を達成できます。ただし、圧縮と解凍には厄介で時間がかかります。

1000 は 2 10よりわずかに小さいため、10 ビットを使用して 3 桁を表すことができるため、最適に近い解が得られます。理論的に最適な 3.32 ビット/桁と比較すると、これは 3.33 ビット/桁です。(つまり、約 99.7% 最適です。)

実際には 1024 の可能な 10 ビット コードがあり、3 桁を表すのに 1000 個しか必要ないので、いくらか残ります。必要に応じて、そのうちの 1 つを使用してストリームの終わりを示すことができます。

10 ビットの数値を出力するのは少し面倒です。40 ビットは正確に 5 バイトであるため、40 ビットの数値を出力する方が簡単です。幸いなことに、最近のほとんどの言語は 40 ビット演算 (実際には 64 ビット演算) をサポートしています。

(注:これはあなたのソリューションとそれほど違いはありません。しかし、少し簡単で、もう少し圧縮されています。)

于 2013-08-07T03:51:08.370 に答える