0

数値の 20 ~ 40文字サイズを6文字サイズの数値に圧縮する必要があります。これまでのところ、ハフマンといくつかのZipアルゴリズムを試しましたが、望ましい結果が得られませんでした。

Javaでこの作業を行うための他のアルゴリズム/ APIについて教えてください。

例:

Input: 98765432101234567890
Desired Output: 123456

注意: 与えられた入力に対して出力が 12345 でなければならないという意味ではありません。20 バイトの数値を指定した場合は、6 バイトの数値に圧縮する必要があるということだけを意味します。

使用法:圧縮された数値がデバイスに供給されます (最大 6 文字の数字しか使用できません)。デバイスは番号をデコードして元の番号に戻します。

前提/制限:

  1. 必要に応じて、クライアントとデバイス (サーバー) の両方が、数値のエンコード/デコードに必要ないくつかの共通プロパティを共有できます。

  2. デバイスに対して行うことができるリクエストは 1 つだけです。つまり、すべてのデータを 1 つのリクエストで送信する必要があり、小さなパケットのチャンクではありません。

ありがとう。

4

2 に答える 2

7

これは、数字の任意の組み合わせが正当な入力であると仮定すると、得られる最高のものになります。

final String s = "98765432101234567890";
for (byte b : new BigInteger('0'+s).toByteArray()) 
  System.out.format("%02x ", b & 0xff);

版画

05 5a a5 4d 36 e2 0c 6a d2

数値をバイナリ形式で格納することは、理論的には最も効率的な方法です。これは、ビットのすべての組み合わせが個別の正当な値であるためです。

入力に冗長性がある場合、つまり有効な数字の組み合わせにいくつかの制約がある場合にのみ、他のオプションを使用できます。

于 2012-06-25T10:40:20.657 に答える
2

あなたがそれを指定する方法では、これは不可能です。単純に 20 桁の数は 6 桁の数よりも多いため、20 桁を 6 桁のみにマップすると、20 桁の数を同じ 6 桁の数にマップする必要があります。すべての数値が有効であるとは限らない、または可能性が同じであるとは限らないことがわかっている場合は、これを圧縮に使用できますが、それ以外の場合は不可能です。

20 桁の数字から 6 桁の数字への可逆 (全単射) マッピングは不可能ですが、長い数字を短い出力にマッピングすることは可能です。これは、出力が数値である必要があるという要件を減らすことで機能します。唯一の重要な考慮事項は、出力シーケンスが入力と同じ数の可能性を持つ必要があるということです。次に例を示します。

  • 20桁の数字は10^20通りあります
  • 長さ x の完全な 8 ビット ASCII (256 文字) のシーケンスを使用すると、256^x の出力が可能になります。これを x について解くと、256^9 > 10^20 なので、20^10 の数値入力をエンコードするには 9 つの ASCII 文字で十分であることがわかります。

同じ質問に対するマルコの答えは、数値を入力として使用できるバイト表現に変換する方法を教えてくれます。ただし、この入力は数値ではなく、多くの奇妙な記号が含まれている可能性があることに注意してください。

于 2012-06-25T10:58:06.783 に答える