//presented by Maskros - 2021/05/20
#include<bits/stdc++.h>
using namespace std;
vector<char> s; //Save the original text
string s2=""; //Save the original text after encoding
map<char,int> mp; //Count the number of occurrences of letters
map<char,string> hfcode; //Save Huffman Code
int len,len2; //Text length
map<char,int>::iterator it;
map<char,string>::iterator it2;
struct Node{int value;char alpha;Node *lchild,*rchild;string code;Node(){}Node(int v,char a,Node *l,Node *r):value(v),alpha(a),lchild(l),rchild(r){code="";}
};
Node *HTroot;
void write_file(char *name){ //Write filecout<<"Print \'*\' to stop typing...."<<endl<<endl;char ch;if(FILE *fp=fopen(name,"w")){while(1){ch=getchar();if(ch=='*') break; //while read '*' then end inputfputc(ch,fp);s.push_back(ch);}fclose(fp);}
}
void cal_alpha(vector<char> v,int l){ //Count the number of words appearing in a letterfor(int i=0;i<l;i++){if((v[i]<='Z'&&v[i]>='A')||(v[i]<='z'&&v[i]>='a'))mp[v[i]]++;}
}
void print_times(){ //Print the number of occurrences and the number of each letterit=mp.begin();putchar('\n');cout<<"n="<<mp.size()<<endl;while(it!=mp.end()){cout<<it->first<<": "<<it->second<<endl; it++;}putchar('\n');
}
struct cmp{ //Used for priority queue sortingbool operator()(Node *a,Node *b){return a->value>b->value;}
};
void create_HT(){ //Build Huffman Treepriority_queue<Node*,vector<Node*>,cmp> q;for(it=mp.begin();it!=mp.end();it++){q.push(new Node(it->second,it->first,NULL,NULL));}if(mp.size()==1){HTroot=q.top(); return;} //Huffman tree has only one root nodeNode *left,*right;while(1){left=q.top(); q.pop();right=q.top(); q.pop();if(q.empty()){HTroot=new Node(left->value+right->value,'0',left,right);break;} q.push(new Node(left->value+right->value,'0',left,right));}
}
void encode_HT(Node *p,string ss){ //Coding the Huffman treeif(!p) return;p->code=ss;if(p->alpha!='0'){if(p->code.length()==0){ hfcode[p->alpha]="1"; return;} //If the Huffman tree has only one root node, the default is 1hfcode[p->alpha]=p->code; }encode_HT(p->lchild,ss+"0");encode_HT(p->rchild,ss+"1");
}
void print_hfcode(){ //Print Huffman codefor(it2=hfcode.begin();it2!=hfcode.end();it2++){cout<<it2->first<<" => "<<it2->second<<endl;}
}
void encode_Text(char *name){ //Write the encoded original text to the filechar tmp[100];string st;if(FILE *fp=fopen(name,"w")){for(int i=0;i<len;i++){ st=hfcode[s[i]];s2+=st;strcpy(tmp,st.c_str()); //String to char arrayfputs(tmp,fp);}fclose(fp);}
}
void decode_Text(char *name){ //Decode b.txt and save in c.txtNode *tmp=HTroot;char decode[10000];int j=0;if(mp.size()==1){ //If the Huffman tree has only one root nodefor(int i=0;i<s2.length();i++){if(tmp->alpha!='0') decode[j++]=tmp->alpha; }}else{for(int i=0;i<=s2.length();i++){if(tmp->alpha!='0'){decode[j++]=tmp->alpha;tmp=HTroot;}if(s2[i]=='0') tmp=tmp->lchild;else tmp=tmp->rchild;}}if(FILE *fp=fopen(name,"w")){ for(int i=0;i<j;i++) fputc(decode[i],fp);fclose(fp);}
}
int main(){char a[]="a.txt";char b[]="b.txt";char c[]="c.txt";write_file(a);len=s.size();cal_alpha(s,len);print_times();create_HT();encode_HT(HTroot,"");print_hfcode();encode_Text(b);decode_Text(c);return 0;
}
實驗用測試數據和相關結果分析
Test 1
The quick brown fox
jumps
over the lazy dog.Test 2
aaaaaTest 3
bbcbaaaad