/* mbinary ######################################################################### # File : huffman.cc # Author: mbinary # Mail: zhuheqin1@gmail.com # Blog: https://mbinary.coding.me # Github: https://github.com/mbinary # Created Time: 2018-04-25 22:32 # Description: ######################################################################### */ #include #include #include #include #include #include #include #include #include #include #include #define numDigit 10 #define nameLength 50 #define starNum 80 using namespace std; void cat(string s) { FILE* f=fopen(s.c_str(),"rb"); cout<<"file content"< void mapprint(map &f) { for(class map::iterator i = f.begin();i!=f.end();++i) cout<first<<") : "<second< class node { public: ky key; wt val; bool visited; node * left,*right; node(const node &a){val = a.val;key= a.key;visited = a.visited;left= a.left;right=a.right;} node(ky k=0,wt v=0):key(k),val(v),visited(false),left(NULL),right(NULL){}; bool operator<(const node & a)const{return val>a.val;}; }; template class huffman { private: node root; string res; public: long total(){return root.val;} map encode_map; map decode_map; huffman(map& mp); void display(); string encode(string,long &); string decode(string,long&); void preOrder(node*,string); }; template huffman::huffman(map& mp) { if(mp.empty()){ cout<<"Error! No data!"< > hp; for(typename map::iterator i=mp.begin();i!=mp.end();++i){ hp.push( node(i->first,i->second)); } int n =hp.size(); if(n==1){ root = hp.top(); return; } while(--n>=1){ node *a = new node(hp.top()); hp.pop(); node *b = new node(hp.top()); hp.pop(); node * tmp = new node(0,a->val+b->val); tmp->left = a,tmp->right = b; hp.push(*tmp); } root = hp.top(); preOrder(&root,string()); } template void huffman::preOrder(node* nd,string s) { if(nd->left == NULL){ encode_map[nd->key] =s; decode_map[s] = nd->key; delete nd; return ; } preOrder(nd->left,s+'0'); preOrder(nd->right,s+'1'); delete nd; } template string huffman::decode(string zipfile_name,long &charNum) { string uniFileName(string); FILE * src = fopen(zipfile_name.c_str(),"rb"); char file_name[nameLength]; fgets(file_name,nameLength,src); int ct=-1; while(file_name[++ct]!='\n'); int pos = zipfile_name.find('.'); if(pos==string::npos)pos=zipfile_name.size(); string name(zipfile_name.substr(0,pos)) ,suffix(file_name,file_name+ct),file(name+suffix); file=uniFileName(file); cout<<"extracting compressed file :"< string huffman::encode(string file_name,long &charNum) { charNum=0; string uniFileName(string); int pos =file_name.rfind('.'); if(pos==string::npos)pos=file_name.size(); string zipfile = file_name.substr(0,pos)+string(".zzip"); zipfile = uniFileName(zipfile); cout<<"generating zip file :"<::iterator i=decode_map.begin();i!=decode_map.end() ;++i ){ data.append((i->first)); data.append(" "); data+=(i->second); } int data_size = data.size(); // calculate the size of the code_data char sz[numDigit]; snprintf(sz,numDigit,"%d",data_size); int ct=0; for(;sz[ct];++ct)fputc(sz[ct],dst); fputc('\n',dst); fwrite(data.c_str(),data_size,1,dst); int sum=0,digit=0,num; string code8; for(int i=0;i void huffman::display() { cout<<"the encoding map,huffman codes are as bellow:"<::iterator i=encode_map.begin();i!=encode_map.end() ;++i ) cout<first<<"("<<(int)i->first<<"):"<second< &origin,vector &compressed) { int name_length = file_name.size(); FILE *src=fopen(file_name.c_str(),"rb"); cout<<"opening "< mp; while(!feof(src)){ fread(&cur,sizeof(char),1,src); if(mp.count(cur)){ mp[cur]+=1; } else mp[cur]=1; } fclose(src); huffman hf(mp); long sz; string s(hf.encode(file_name,sz)); origin.push_back(hf.total()),compressed.push_back(sz); cout<<"\ncontinue to uncompress? [Y/n]"<& v) { int i=0,last=0; for(;s[i];++i){ if(isSep(s[i])){ v.push_back(string(s+last,s+i)); while(s[++i]&&isSep(s[i])); last=i; } } if(s[last])v.push_back(string(s+last,s+i)); } bool lenStr(string &a,string &b) { return a.size() & names) { vector originSize,compressedSize; vector deltaTime; double last; vector indicator; bool bl; for(vector::iterator i=names.begin();i!=names.end();++i){ struct timeval tv; gettimeofday(&tv,NULL); last=tv.tv_sec; bl=handle_one(*i,originSize,compressedSize); indicator.push_back(bl); gettimeofday(&tv,NULL); deltaTime.push_back(tv.tv_sec-last); } cout<<"\nDealt file number "<::iterator p=max_element(names.begin(),names.end(),lenStr); int len = p->size()+2; for(int i =0;i names; string file; if(argv>1){ for(int i=1;i