本問題是來自於課堂上老師關於貪心問題的第三講.huffman編碼是最有效的二進位制編碼,其中貪心策略主要體現在根據頻度來設定編碼長度.最早在資料結構的便有學習到,當時採用的建樹方式是帶指標的結構體+小頂堆(使用小頂堆的優勢在於堆是動態的,同時也有較高的效率——插入和刪除並調整的效率約為o(lgn),查詢最小的效率為o(1)),從理論上來說也是比較容易理解的.然而在一般的做題中我們實際只需要用陣列模擬即可(好吧,其實也是因為沒有學過c++裡的堆模板).比較慚愧的是好久沒寫建樹相關的內容了,差點不會寫了,因此這裡記錄一下.
在課堂上,我們學習了哈夫曼編碼的原理和實現方法,上實驗課時也動手實現過,後來我們又追加介紹了哈夫曼編碼的實際壓縮和解壓縮的實現方法,並且在課堂上也演示了,但當時我們卻忽略了乙個環節,那就是實際檔案儲存時,二進位制是位元位,而儲存的單位一般是位元組,顯示時又是按照十六進製制的。現在給你乙個已經用哈夫曼方法壓縮過的十六進製制檔案,請你解壓以便還原成原文。
本問題有多組測試資料,第一行就是測試資料的組數ncase,對於每組測試資料,一共有四個部分,第一部分是乙個字典(請注意,字典裡可能含有空格!),原文本裡面出現的任何字元一定在這個字典裡面,並且已經按照使用頻度從大到小順序排列。第二部分是字典裡相對應字元的使用頻度。第三部分是待解壓的行數n。第四部分是n行經過哈夫曼壓縮的十六進製制數組成的字串。
輸出一共n行,每行就是對應輸入的原文(請注意,輸出的原文裡可能含有空格!)。
1
aorst
60 22 16 13 6 457c
f3f2cc3c6fe24d3fc5ab7cc6
98bbd266c6ff81
fe6517f5b6663af98fe2226676fa80
f317262fcfe662fc99d7d
ao
asao rst atoaats osaatrr rrasto
stroar ssrtoaaa ||error !
aass traa rrrssta rastaatttsssooaor
astro strao aasstrao ssorar
哈夫曼編碼介紹
依據要求,關於編碼我們可以確立兩個基本的準則:
基於霍夫曼樹,我們只要對樹的左右邊進行標號即可——左0右1或者左1右0,由此我們可以得出霍夫曼編碼的另乙個特定是不唯一.最終的編碼(以左0右1為例):
序號符號
huffman編碼11
0002201
3314
4001
注:有時對於同乙個字典可以構造不同形式的huffman(如頻度相同的字典),也就是異構的.
huffman構造
解碼擴充套件
#include #include #include #include #include #include #include #define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int n=1e3+10;
typedef structnode;
node arr[2*n];
int maxlen;
//將code向原文對映
mapcodemap;
void getcode(int index,string str);
string hextobin(string str);
int max(int a,int b);
int main()
codemap.clear();
char temp;
scanf("%*c%c",&temp);
n=0; //忘記初始化的垃圾!!!
while(temp!='\n')
for(int i=1;i<=n;i++)
//做結構化的消解,(2*n-1)-(n)
arr[0].weight = inf;
int num=n; //記錄所有節點個數
for(int i=1;i<=n-1;i++)else if((int)temp.length() > maxlen)
}if(temp != "")
cout << endl;}}
}return 0;
}void getcode(int index,string str)
getcode(arr[index].left,str+'0');
getcode(arr[index].right,str+'1');
}int max(int a,int b)
string hextobin(string str);
string ans = "";
int len = str.length(),temp;
for(int i=0;i='a')else
ans += htobin[temp];
}return ans;
}
注:由於寫完已經錯過了交題的時間,**只通過了樣例,恐怕還有些細節性的問題(對於這點我應該很有信心!!!)
注(11.25):**已更新,因為沒有去掉除錯的兩個內容導致錯了好幾發,最後還是提交成功了,但是之所以能ac的原因個人推測還是老師資料太弱了!
哈夫曼編碼的乙個實際應用(壓縮)
在課堂上,我們學習了哈夫曼編碼的原理和實現方法,上實驗課時也動手實現過,後來我們又追加介紹了哈夫曼編碼的實際壓縮和解壓縮的實現方法,並且在課堂上也演示了,但當時我們卻忽略了乙個環節,那就是實際檔案儲存時,二進位制是位元位,而儲存的單位一般是位元組,顯示時又是按照十六進製制的。現在給你乙個由字典裡的字...
哈夫曼樹的應用 哈夫曼編碼
include include include 樹結點定義 typedef struct htnode,huffmantree static char n 100 用於儲存正文 哈弗曼編碼,char型二級指標 typedef char huffmancode 封裝最小權結點和次小權結點 typede...
哈夫曼樹的建立以及哈夫曼編碼
主要源 如下 include include define max num 105 typedef struct htnode,htree void selecttwomin htree ht,int n,int s1,int s2 ht s1 visited 1 將最小的頻率對應的結點標記為已被訪...