huffman編碼——原理與實現
阿新 • • 發佈:2019-01-03
那我們將friend bool operator >(Node node1,Node node2)修改為friend bool operator >(Node* node1,Node* node2),也就是傳遞的是Node的指標行不行呢?
答案是不可以,因為根據c++primer中過載操作符中講的“程式設計師只能為類型別或列舉型別的運算元定義過載操作符,在把操作符宣告為類的成員時,至少有一個類或列舉型別的引數按照值或者引用的方式傳遞”,也就是說friend bool operator >(Node* node1,Node* node2)形參中都是指標型別的是不可以的。我們只能再建一個類,用其中的過載()操作符作為優先佇列的比較函式。
就得到了下面正確的程式碼:
/************************************************************************/ /* File Name: Huffman.cpp * @Function: Lossless Compression @Author: Sophia Zhang @Create Time: 2012-9-26 10:40 @Last Modify: 2012-9-26 12:10 */ /************************************************************************/ #include"iostream" #include "queue" #include "map" #include "string" #include "iterator" #include "vector" #include "algorithm" using namespace std; #define NChar 8 //suppose use 8 bits to describe all symbols #define Nsymbols 1<<NChar //can describe 256 symbols totally (include a-z, A-Z) typedef vector<bool> Huff_code;//8 bit code of one char map<char,Huff_code> Huff_Dic; //huffman coding dictionary /************************************************************************/ /* Tree Class elements: *2 child trees *character and frequency of current node */ /************************************************************************/ class HTree { public : HTree* left; HTree* right; char ch; int weight; HTree(){left = right = NULL; weight=0;ch ='\0';} HTree(HTree* l,HTree* r,int w,char c){left = l; right = r; weight=w; ch=c;} ~HTree(){delete left; delete right;} bool Isleaf(){return !left && !right; } }; /************************************************************************/ /* prepare for pointer sorting*/ /*because we cannot use overloading in class HTree directly*/ /************************************************************************/ class Compare_tree { public: bool operator () (HTree* t1, HTree* t2) { return t1->weight> t2->weight; } }; /************************************************************************/ /* use priority queue to build huffman tree*/ /************************************************************************/ HTree* BuildTree(int *frequency) { priority_queue<HTree*,vector<HTree*>,Compare_tree> QTree; //1st level add characters for (int i=0;i<Nsymbols;i++) { if(frequency[i]) QTree.push(new HTree(NULL,NULL,frequency[i],(char)i)); } //build while (QTree.size()>1) { HTree* lc = QTree.top(); QTree.pop(); HTree* rc = QTree.top(); QTree.pop(); HTree* parent = new HTree(lc,rc,lc->weight+rc->weight,(char)256); QTree.push(parent); } //return tree root return QTree.top(); } /************************************************************************/ /* Give Huffman Coding to the Huffman Tree*/ /************************************************************************/ void Huffman_Coding(HTree* root, Huff_code& curcode) { if(root->Isleaf()) { Huff_Dic[root->ch] = curcode; return; } Huff_code lcode = curcode; Huff_code rcode = curcode; lcode.push_back(false); rcode.push_back(true); Huffman_Coding(root->left,lcode); Huffman_Coding(root->right,rcode); } int main() { int freq[Nsymbols] = {0}; char *str = "this is the string need to be compressed"; //statistic character frequency while (*str!='\0') freq[*str++]++; //build tree HTree* r = BuildTree(freq); Huff_code nullcode; nullcode.clear(); Huffman_Coding(r,nullcode); for(map<char,Huff_code>::iterator it = Huff_Dic.begin(); it != Huff_Dic.end(); it++) { cout<<(*it).first<<'\t'; std::copy(it->second.begin(),it->second.end(),std::ostream_iterator<bool>(cout)); cout<<endl; } }