遊程編碼算法
概述
利用比特流常見的冗餘形式:連續的重複數據,來壓縮數據。
0000000000000001111111000000011111111111 --40bit
在源數據中,記錄重複bit的個數,記錄到壓縮數據中。
1111,0111,0111,1011 --16bit
實現
- 壓縮原理:
- 將源文件中連續的1或0的個數(count)寫到壓縮文件中,
- 比如count用8位表示,規定壓縮文件的格式爲:
- 0連續的個數-1連續的個數-0連續的個數-1連續的個數…..
- 個數的大小爲0~255,
- 如何處理連續的0(或1)的個數過大,無法存到count中:
count0(=255)-count1(=0)-count0(=?)-…….
壓縮
private final static int R = 256; private final static int lgR = 8; //存儲cnt需要多少位 /** * 壓縮 */ private static void compress() { boolean b, old = false; int cnt = 0; //記錄連續的0或1的個數 while (!BinaryStdIn.isEmpty()) { b = BinaryStdIn.readBoolean(); if (b != old) { //該向輸出流寫數據了 BinaryStdOut.write(cnt,lgR); cnt = 0; old = !old; } else { if (cnt == (R - 1)) { // 處理連續的0(或1)的個數過大,無法存到count BinaryStdOut.write(cnt,lgR); //count0(=255)-count1(=0)-count0(=?)-....... cnt = 0; BinaryStdOut.write(cnt,lgR); } } cnt++; } BinaryStdOut.write(cnt,lgR); //把剩餘的cnt寫出 BinaryStdOut.close(); }
解壓
/** * 解壓 */ private static void expand() { boolean bit = false; while (!BinaryStdIn.isEmpty()) { int run = BinaryStdIn.readInt(lgR); //從輸入流中讀取lgR 位,這個數值代表了源文件中連續1或連續0的長度 for (int i = 0; i < run; i++) { //根據run的大小向輸出流中寫位 BinaryStdOut.write(bit); } bit = !bit; //壓縮的格式要求 } BinaryStdOut.close(); }
測試用例
public static void main(String[] args) { if (args[0].equals("-")) compress(); else if (args[0].equals("+")) expand(); else throw new IllegalArgumentException("Illegal command line argument"); }