基於哈夫曼演算法的檔案壓縮軟體

2021-09-03 03:16:22 字數 2503 閱讀 5804

資料結構課設(一)

1、設計並實現乙個使用哈夫曼演算法對檔案進行壓縮的工具軟體。

2、通過命令列引數指定操作模式(壓縮/解壓)、源檔名、目標檔名。

3、壓縮操作將原始檔按位元組讀入並統計位元組頻率,生成位元組的哈夫曼編碼,將編碼樹和用哈夫曼編碼對位元組重新編碼後的結果儲存到目標檔案中。

4、解壓操作將原始檔中的編碼樹讀出,用編碼樹對後續編碼部分進行解碼操作,將解碼結果儲存到目標檔案中。

基於哈夫曼演算法的檔案壓縮要考慮的幾個主要問題:

1、命令列引數的設計與識別。帶引數的main函式應該怎麼用;設計合適的命令列引數來表示要執行的操作、源檔名和目標檔名。

2、檔案操作。c/c++的檔案流庫是不一樣的,選擇你喜歡的檔案流庫,學習怎麼以正確的方式開啟檔案、逐字節讀取檔案、寫入檔案。

3、設計壓縮檔案的格式。壓縮檔案頭部應該是儲存生成的哈夫曼樹,後續才是原始檔的壓縮(編碼)結果。這裡的關鍵是檔案頭的設計。

4、統計位元組頻率,建立哈夫曼樹,構造位元組哈夫曼編碼。

5、對原始檔逐字節進行編碼,並重新組合成位元組。

6、解析壓縮檔案的檔案頭,還原哈夫曼樹。

7、對壓縮檔案的編碼部分進行解碼。

決定按問題順序來乙個個解決。

由於老師給出了demo**,我就直接拿過來用了

int main(int argc, char *argv)

// 檢查命令列引數,如果沒有讀到所需要的命令列引數,提示使用說明

if (argc != 4)

else if (stricmp(argv[1], "z") == 0)

else if (stricmp(argv[1], "e") == 0)

else

return 0;

}

演示

這裡用的是c++的iostream和fstream檔案流庫。用二進位制的方式逐字節讀取檔案,可以讀入文字或者音訊等各種格式。

ifstream instr("in.txt", ios::in | ios::binary);//二進位制方式

if (!instr)

ofstream outstr("out.txt", ios::out | ios::binary);

if (!outstr)

char ch;

while (instr.get(ch))

instr.close();

outstr.close();

return 0;

這一步就是壓縮檔案的關鍵了,決定你壓縮檔案最後的大小,如果設計不合理的話壓縮率和壓縮速度就會極不理想(比如說我的就是),壓縮完之後的壓縮檔案可能比原檔案還要大。

首先壓縮檔案需要存你的哈夫曼樹,然後就是你處理過的檔案的哈夫曼編碼。

檔案壓縮成編碼這一步其實很簡單,就是把原先的檔案通過你構建的哈夫曼轉成01序列的哈夫曼編碼,然後把這些編碼以二進位制的形式存進壓縮檔案就行了。我是每8個位元組轉成乙個unsigned char,然後存入檔案。解壓縮的時候再把這個還原成哈夫曼編碼的形式就行了。

如果只需要存哈夫曼編碼檔案,不需要對應的哈夫曼樹的話,那麼大部分檔案是可以壓縮的更小的。但是,通常我們解壓縮是只需要對壓縮檔案進行操作的,如果壓縮檔案裡只存有哈夫曼編碼的資訊,那麼我們是無法進行解碼的。因此我們必須存進對應的哈夫曼樹,這樣才能解碼還原成原檔案。

不過直接將整棵樹全部存進去會使你的壓縮檔案變得極其大,對於原本體積小的檔案比如只有幾十位元組的txt文字來說,壓縮完之後一下子就變成幾百位元組的東西了。由於我一開始沒考慮到這令人窒息的情況,等我全部寫完已經提不起興致去改了,最後做出來的程式對比較大的檔案才能起到一定的壓縮效果。

string str(string s)//將01二進位制數轉換成字元

void show()

for(int i=0;it,map&code)

else c.push('1');}}

else break;

while(!c.empty())

code[t[i].name]=s;

}return 0;

}int main()

else s+='0';}}

int sur=8-n%8;

while(sur--)

return s;

}int uncode(vectort,string t,int sur,char *file)

ss.close();

uncode(t0,t,f2,file2);

cout<

大概總結一下,其實這個演算法算是比較簡單的,難點主要在如何進行二進位制檔案的操作,這些格式轉換的亂七八糟的,網上找又不好找,沒有統一的方法,只有自己慢慢摸索。經過這幾天的學習,好歹熟悉了fstream/ifstream/ofstream這幾個檔案流的使用。

以後原始碼都上傳到我的github上。(假裝自己寫了很多東西的樣子)

基於哈夫曼編碼的檔案壓縮

本篇主要介紹如何利用哈夫曼編碼使檔案進行壓縮 如何構建哈夫曼樹 歡迎提出問題和建議 blbagony 163.com 鏈結 哈夫曼樹template struct huffmannode 構建樹 huffman tree 是構造出來的物件,size返回樹中結點個數 每取乙個 top 就 pop 一次...

哈夫曼壓縮演算法

給你40分鐘的時間,你可以思考十分鐘,然後用三十分鐘的時間來寫 最後浪費在無謂的除錯上 你也可以思考半個小時,徹底弄清問題的本質與程式的脈絡,然後用十分鐘的時間來編寫 體會 如行雲流水而出的感覺。在程式設計過程當中,相信大家都深有體會,在除錯上浪費時間,問題出現在下筆之前沒有乙個系統結構。哈夫曼在通...

檔案壓縮(哈夫曼壓縮)

檔案壓縮總結 哈夫曼壓縮 在學習哈弗曼壓縮之前,還是首先來了解什麼是哈夫曼樹,哈夫曼編碼。1.哈夫曼樹是一種最優二叉樹,它的帶權路徑長度達到最小。樹的帶權路徑長度為所有葉子結點帶權路徑長度之和。而結點的帶權路徑長度是結點的路徑長度乘以結點的權值。2.哈夫曼編碼是依據字元出現概率來構造異字頭的平均長度...