私はハフマン圧縮アルゴリズムに取り組んでいます。各キャラのコードをまとめました。例えば f=1100
d=111
e=1101
b=101
c=100
a=0
ここで、圧縮を実現するために、コードをビットとしてバイナリ ファイルに書き込む必要があります。私は今、それらをバイトとして書き込むことができます。これは、圧縮ファイルのサイズを増やすだけです。コードをビットとしてJavaのバイナリファイルに書き込むにはどうすればよいですか?
私はハフマン圧縮アルゴリズムに取り組んでいます。各キャラのコードをまとめました。例えば f=1100
d=111
e=1101
b=101
c=100
a=0
ここで、圧縮を実現するために、コードをビットとしてバイナリ ファイルに書き込む必要があります。私は今、それらをバイトとして書き込むことができます。これは、圧縮ファイルのサイズを増やすだけです。コードをビットとしてJavaのバイナリファイルに書き込むにはどうすればよいですか?
Well if you have the text "fdebcafdbca" you would need to write that as the bits:
110011111011011000110011111011011000
Separated and padded:
11001111 10110110 00110011 11101101 10000000 //4 bits of padding here
In hexadecimal:
CF B6 33 ED 80
したがって、バイト配列を0xCF 0xB6 0x33 0xED 0x80
ファイルに書き込みます。つまり、5 バイト = 40 ビットで、4 ビットが無駄になります。テキストはもともと 12 バイトかかるため、ツリーも保存する必要があるため、あまり節約できません。パディングがバイト境界に整列しない場合、パディングの使用を避けることはできません。
まったく推奨されませんが、文字列がある場合は、次のようにすることができます。
public class BitWriter {
private byte nthBit = 0;
private int index = 0;
private byte[] data;
public BitWriter( int nBits ) {
this.data = new byte[(int)Math.ceil(nBits / 8.0)];
}
public void writeBit(boolean bit) {
if( nthBit >= 8) {
nthBit = 0;
index++;
if( index >= data.length) {
throw new IndexOutOfBoundsException();
}
}
byte b = data[index];
int mask = (1 << (7 - nthBit));
if( bit ) {
b = (byte)(b | mask);
}
data[index] = b;
nthBit++;
}
public byte[] toArray() {
byte[] ret = new byte[data.length];
System.arraycopy(data, 0, ret, 0, data.length);
return ret;
}
public static void main( String... args ) {
BitWriter bw = new BitWriter(6);
String strbits = "101010";
for( int i = 0; i < strbits.length(); i++) {
bw.writeBit( strbits.charAt(i) == '1');
}
byte[] b = bw.toArray();
for( byte a : b ) {
System.out.format("%02X", a);
//A8 == 10101000
}
}
}