题目描述
已知赫夫曼编码算法和程序,在此基础上进行赫夫曼解码
可以增加一个函数:int Decode(const string codestr, char txtstr[]);//输入编码串codestr,输出解码串txtstr
该方法如果解码成功则返回1,解码失败则返回-1,本程序增加宏定义ok表示1,error表示-1
赫夫曼解码算法如下:
定义指针p指向赫夫曼树结点,指针i指向编码串,定义ch逐个读取编码串的字符
初始操作包括读入编码串str,设置p指向根结点,i为0表示指向串首,执行以下循环:
1)取编码串的第i个字符放入ch
2)如果ch是字符0,则p跳转到左孩子;如果ch是字符1,则p跳转到右孩子;如果ch非0非1,表示编码串有错误,报错退出
3)如果p指的结点是叶子,输出解码字符,p跳回根结点,i++,跳步骤1
4)如果p指的结点不是叶子且i未到编码串末尾,i++,跳步骤1
5)如果p指的结点不是叶子且i到达编码串末尾,报错退出
当i到达编码串末尾,解码结束。
输入
第一行先输入n,表示有n个叶子
第二行输入n个权值,权值全是小于1万的正整数
第三行输入n个字母,表示与权值对应的字符
第四行输入k,表示要输入k个编码串
第五行起输入k个编码串输入样例:
5
15 4 4 3 2
A B C D E
3
11111
10100001001
00000101100
输出
每行输出解码后的字符串,如果解码失败直接输出字符串“error”,不要输出部分解码结果
输出样例:
AAAAA
ABEAD
error
代码
#include <iostream>
using namespace std;
struct Node{
char data;
int weight;
int parent;
int lchild;
int rchild;
};
class HuffmanTree{
Node *list;
int n,m1,m2;
public:
string s;
HuffmanTree(){
cin >> n;
list = new Node[2*n];
for(int i = 1; i < 2*n; i++){
if(i >= 1 && i <= n){
cin >> list[i].weight;
}else{
list[i].weight = 0;
}
list[i].parent = 0;
list[i].lchild = 0;
list[i].rchild = 0;
}
for(int i = 1; i <= n; i++){
cin >> list[i].data;
}
}
void makeTree(){
int k = n+1;
while(k < 2*n){
getMin(k);
list[k].weight = list[m1].weight + list[m2].weight;
list[k].lchild = m1;
list[k].rchild = m2;
list[m1].parent = k;
list[m2].parent = k;
k++;
}
}
void getMin(int k){
int min1 = 9999, min2 = 9999;
m1 = m2 = 0;
for(int i = 0; i < k; i++){
int temp = list[i].weight;
if(list[i].parent == 0 && temp < min2){
if(temp >= min1){
min2 = temp;
m2 = i;
}else{
min2 = min1;
min1 = temp;
m2 = m1;
m1 = i;
}
}
}
}
int decode(){
s = "";
string code;
int len,root;
cin >> code;
len = code.length();
for(int i = n+1; i < 2*n; i++){
if(list[i].parent == 0){
root = i;
break;
}
}
int v=root, i=0;
while(i < len){
if(code[i] == '0'){
if(list[v].lchild != 0){
v = list[v].lchild;
}else{
return -1;
}
}else{
if(list[v].rchild != 0){
v = list[v].rchild;
}else{
return -1;
}
}
if(i == len-1 && v > n){
return -1;
}
if(list[v].lchild == 0 && list[v].rchild == 0){
s += list[v].data;
v = root;
}
i++;
}
return 1;
}
};
int main()
{
HuffmanTree tree;
tree.makeTree();
int k;
cin >> k;
while(k--){
int v = tree.decode();
if(v == -1){
cout << "error" << endl;
}else{
cout << tree.s << endl;
}
}
return 0;
}