亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++ 哈夫曼樹對文件壓縮、加密實現代碼

2020-01-26 13:57:26
字體:
來源:轉載
供稿:網友

在以前寫LZW壓縮算法的時候,遇到很多難受的問題,基本上都在哈夫曼編碼中解決了,雖然寫這代碼很費神,但還是把代碼完整的碼出來了,畢竟哈夫曼這個思想確實很牛逼。哈夫曼樹很巧妙的解決了當時我在LZW序列化的時候想解決的問題,就是壓縮后文本的分割。比如用lzw編碼abc,就是1,2,3。但這個在存為文件的時候必須用分割符把1,2,3分割開,非常浪費空間,否則會和12 23 123 產生二義性。而哈夫曼樹,將所有char分布在葉節點上,在還原的時候,比如1101110,假設110是葉節點,那么走到110的時候就可以確定,已經走到盡頭,回到根節點繼續走,這樣就避免了字符的分割,全部用1010101010101這樣的路徑表示字符,可以將8位壓縮為1個char進行存儲。在構造樹的時候,將出現率高的char放在上面,這樣路徑就很短,自然就節省了存儲空間。雖然哈夫曼壓縮效率不是最高的,但還算比較樂觀的。

哈夫曼除了壓縮以外還可以用于加密,在將文本用哈夫曼編碼時,需持久化生成的char計數鏈表結構,這樣才能還原出樹結構,而解碼時路徑正是依賴于樹結構的。也就是說,這種編碼是屬于約定形式的編碼,在編碼時用原文本產生樹結構,而存儲的是樹路徑,解碼的時候缺少樹或樹結構與原先不相符都是無法完成解碼的,就好比,我用10代表a,你存的是10,你將10解釋為 b或c等等都是不正確的。由于轉換為了char存儲,所以還需持久化最后填充的數目、文本長度,才能還原出原先的01表示的文本格式

這個代碼有一定缺陷,由于當時考慮的是對文本進行處理,當文件中有char='/0' 時會出現錯誤,這個代碼打的很費神,就不繼續修復了,如有需要,可自行更改,解決的辦法應該挺多的

先來個運行圖:

源代碼

#include<iostream> #include<sstream> #include<fstream>  void WriteFile(char* path,const char* content,int length,bool append=false); using namespace std; struct Node{    char data;   Node* left;   Node* right;  };  struct L_Node{   int count;   Node* node;   L_Node* next; };  Node* AddNode(int count,char data,L_Node*& first){   L_Node* lnode=new L_Node();   lnode->count=count;   Node* node=new Node();   node->data=data;   node->left=0;   node->right=0;   lnode->node=node;   if(first==0){     first=lnode;   }   else{     if(lnode->count<first->count){       lnode->next=first;       first=lnode;     }     else{       L_Node* iter=first;              while(iter->next!=0&&iter->next->count<lnode->count){         iter=iter->next;       }              if(iter->next==0){         iter->next=lnode;         lnode->next=0;       }       else{         lnode->next=iter->next;         iter->next=lnode;       }     }   }   return node; }  void SaveLNodes(L_Node* first){   stringstream ss;   while(first!=0){     ss<<(int)(unsigned char)first->node->data<<':'<<first->count<<' ';     first=first->next;   }   WriteFile("nodes.txt",ss.str().c_str(),ss.str().length()); }  void GetLNodes(L_Node*& first){   char temp[32];   ifstream in;   in.open("nodes.txt",ios::in|ios::binary);   while(!in.eof()){     temp[0]=0;     in>>temp;     if(strlen(temp)>0){       char* data=strtok(temp,":");       char* count=strtok(0,":");       AddNode(atoi(count),atoi(data),first);     }        } }  void BuildSortedList(char* content,L_Node*& first,int length){   int array[256]={     0   };    for(int i=0;i<length;i++){     array[(unsigned char)content[i]]++;   }    for(int i=0;i<256;i++){     if(array[i]>0){       AddNode(array[i],(char)i,first);     }   }   SaveLNodes(first); }  void BuildTree(L_Node*& first,Node*& root){//get l1->node,l2->node,remove l1,l2,then put l3 into list,then set l3->left and l3->right   if(first->next==0){     Node* node=new Node();     root=node;     root->right=0;     node=new Node();     node->data=first->node->data;     node->left=0;     node->right=0;     root->left=node;     delete first;     return;   }         while(first->next!=0){     int count=first->count+first->next->count;     Node* node1=first->node;     L_Node* temp=first;     first=first->next;     delete temp;     Node* node2=first->node;     temp=first;     delete temp;     first=first->next;     root=AddNode(count,0,first);     root->left=node1;     root->right=node2;     //cout<<(int)node1->data<<':'<<(int)node2->data<<endl;   }   delete first; }  void PreOrderTraversal(Node* node,char* track,int branch,char** table){   if(node!=0){          char* track2=0;          if(branch==0){       track2=new char[strlen(track)+2];       sprintf(track2,"%s0/0",track);     }     else if(branch==1){       track2=new char[strlen(track)+2];       sprintf(track2,"%s1/0",track);     }     else{       track2=new char[strlen(track)+1];       sprintf(track2,"%s/0",track);     }        if(node->data!=0){       table[(unsigned char)node->data]=track2;     }          PreOrderTraversal(node->left,track2,0,table);     PreOrderTraversal(node->right,track2,1,table);             if(node->data==0){       delete track2;     }   } }  void PreOrderTraversal(Node* node){   if(node!=0){     cout<<(int)(unsigned char)node->data<<endl;     PreOrderTraversal(node->left);     PreOrderTraversal(node->right);   } }  char* Encode(const char* content,char** table,int length){      stringstream ss;    for(int i=0;i<length;i++){     if((unsigned char)content[i]==0){      }     else{       ss<<table[(unsigned char)content[i]];      }   }         char* encoded_content=new char[ss.str().length()+1];   memcpy(encoded_content,ss.str().c_str(),ss.str().length());   encoded_content[ss.str().length()]=0;   return encoded_content; }  int BinToDec(char* bin_content){   int number=0;   int cur=1;    for(int i=7;i>=0;i--){     number+=(bin_content[i]-'0')*cur;     cur*=2;   }   return number; }   char* BinToCharText(const char* bin_content,int& fill_count,int& save_length){   int length=strlen(bin_content);      fill_count=8-length%8;    if(fill_count>0){     char* temp=new char[length+fill_count+1];          char temp1[fill_count];     for(int i=0;i<fill_count;i++){       temp1[i]='0';     }          sprintf(temp,"%s%s",bin_content,temp1);     temp[length+fill_count]=0;     bin_content=temp;   }      length+=fill_count;      save_length=length/8;    char* text=new char[length/8+1];   for(int i=0;i<length;i+=8){     char temp[8];     memcpy(temp,bin_content+i,8);     text[i/8]=(char)BinToDec(temp);       }   text[length/8]=0;      if(fill_count>0){     delete bin_content;   }      return text; }  char* DecToBin(int num){   char* bin=new char[8];   if(num<0){     num=256+num;   }      for(int i=7;i>=0;i--){     bin[i]=num%2+'0';     num/=2;   }   return bin; }  char* CharTextToBin(char* text,int fill_count,int save_length){   int length=save_length;    char* content=new char[8*length+1];      int pos=0;   for(int i=0;i<length;i++){     int number=text[i];     char* bin=DecToBin(number);     memcpy(content+pos,bin,8);     pos+=8;     delete bin;   }      content[8*length-fill_count]=0;    return content; }  char* Decode(const char* encode_content,Node* tree){   stringstream ss;   Node* node=tree;    for(int i=0;i<strlen(encode_content);i++){     if(encode_content[i]=='0'){       node=node->left;     }     else if(encode_content[i]=='1'){       node=node->right;     }      if(node->data!=0){       ss<<node->data;       node=tree;     }   }   char* decode_content=new char[ss.str().length()+1];   memcpy(decode_content,ss.str().c_str(),ss.str().length());   decode_content[ss.str().length()]=0;   return decode_content; }   void ReleaseTable(char** table){   for(int i=0;i<256;i++){     if(table[i]!=0){       delete table[i];     }   } }  void PostOrderTraversal(Node* node){   if(node!=0){     PostOrderTraversal(node->left);     PostOrderTraversal(node->right);     delete node;   } }   char* ReadFile(char* path,long& length){   char* content=0;   ifstream in;   in.open(path,ios::in|ios::binary);   in.seekg(0,ios::end);   length=in.tellg();   content=new char[length+1];   in.seekg(0,ios::beg);   int i=0;   while(!in.eof()){     content[i++]=in.get();   }   content[length]=0;   in.close();   return content; }  char* ReadFile(char* path,int& fill_count,int& save_length){   char* content=0;   ifstream in;   in.open(path,ios::in|ios::binary);   in>>fill_count>>save_length;   long cur=in.tellg()+(long)1;   in.seekg(0,ios::end);   long length=in.tellg()-cur;   content=new char[length+1];   in.seekg(cur,ios::beg);   int i=0;   while(!in.eof()){     content[i++]=in.get();   }   content[length]=0;   in.close();   return content; }  void WriteFile(char* path,const char* content,int length,bool append){   ofstream out;   if(append){     out.open(path,ios::out|ios::binary|ios::app);   }   else{     out.open(path,ios::out|ios::binary);   }      out.write(content,length);   out.close(); }  int main(){   long length;   char* content=ReadFile("content.txt",length);    L_Node* first=0;      BuildSortedList(content,first,length); //create nodes list and save to nodes file   //GetLNodes(first);//get and recreate nodes from file    Node* root=0;//used for buildtable and decode   BuildTree(first,root);//build tree by nodes list and release sorted list      char* table[256]={//build table,used for encode     0   };    PreOrderTraversal(root,"",-1,table);//create table       char* encode_content=Encode(content,table,length);//convert content to encoded bin text   cout<<encode_content<<endl;   delete content;      ReleaseTable(table);//release table when encode finished         int fill_count;   int save_length;   char* save_text=BinToCharText(encode_content,fill_count,save_length);//convert encoded bin text to char text and save these text to file   delete encode_content;   char head_info[32];   sprintf(head_info,"%d %d ",fill_count,save_length);   WriteFile("encoded_content.txt",head_info,strlen(head_info));   WriteFile("encoded_content.txt",save_text,save_length,true);   delete save_text;   save_text=ReadFile("encoded_content.txt",fill_count,save_length);//read fill_count、save_length、encoded char text from file      char* bin_text= CharTextToBin(save_text,fill_count,save_length);//convert char text to bin text   delete save_text;      char* decode_content=Decode(bin_text,root);//decode by bin_text and tree   cout<<decode_content<<endl;   delete bin_text;   delete decode_content;         PostOrderTraversal(root);//release tree      return 0; } 

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
57pao成人国产永久免费| 色yeye香蕉凹凸一区二区av| 欧美中在线观看| 性色av一区二区三区在线观看| 亚洲伊人一本大道中文字幕| 欧美猛交免费看| 亚洲国产中文字幕在线观看| 欧美麻豆久久久久久中文| 亚洲精选在线观看| 亚洲欧美999| 亚洲片国产一区一级在线观看| 亚洲国模精品私拍| 色多多国产成人永久免费网站| 国外日韩电影在线观看| 国产成人高潮免费观看精品| 中文字幕自拍vr一区二区三区| 欧美午夜xxx| 成人国产精品一区二区| 欧美性猛交xxxx偷拍洗澡| 亚洲高清一区二| 欧美激情精品久久久久久| 77777少妇光屁股久久一区| 国产精品久久久久久影视| 精品国产成人av| 秋霞午夜一区二区| 久久久久久久久久久久久久久久久久av| 日韩av手机在线看| 中文字幕亚洲欧美| 欧美中文字幕在线| 亚洲精品97久久| 韩曰欧美视频免费观看| 成人中文字幕在线观看| 国产成人精品免费久久久久| 日韩欧亚中文在线| 亚洲激情视频在线播放| 欧美裸体xxxx极品少妇| 久久久免费在线观看| 中文字幕欧美精品日韩中文字幕| 欧美影院在线播放| 欧美重口另类videos人妖| 91高潮在线观看| xvideos亚洲| 亚洲欧美日韩高清| 狠狠躁夜夜躁人人爽超碰91| 亚洲美女性视频| 日韩av一区在线观看| 欧美猛交ⅹxxx乱大交视频| 日韩av在线电影网| 欧美在线视频播放| 日韩av中文字幕在线| 欧美精品免费播放| 国产日韩欧美中文在线播放| www高清在线视频日韩欧美| 国产精品爽黄69天堂a| 久久久久久999| 国产成人精品视频在线| 欧美性一区二区三区| 中文字幕日韩电影| 亚洲欧美日韩另类| 精品久久中文字幕| 久久久国产精品一区| 欧美亚洲午夜视频在线观看| 中文精品99久久国产香蕉| 国产亚洲精品美女久久久| 欧美日韩高清在线观看| 国产99久久精品一区二区永久免费| 大荫蒂欧美视频另类xxxx| 懂色av影视一区二区三区| 精品无人国产偷自产在线| 欧美黑人视频一区| 日韩中文娱乐网| 国产日韩精品在线| 欧美肥臀大乳一区二区免费视频| 国产精品狠色婷| 91中文在线视频| 日韩av日韩在线观看| 欧美性猛交xxxx偷拍洗澡| 日韩资源在线观看| 欧美精品一本久久男人的天堂| 欧美一区二区三区免费观看| 久久久欧美精品| 欧美久久精品一级黑人c片| 中文字幕欧美专区| 国产精品自产拍在线观看中文| 91av在线精品| 久久香蕉国产线看观看av| 久久亚洲精品一区| 国产精品扒开腿爽爽爽视频| 亚洲区bt下载| 国产精品∨欧美精品v日韩精品| 亚洲国产天堂久久综合网| 久久久久久久香蕉网| 日韩视频在线一区| 国产亚洲精品久久久久久| 亚洲国产精品人久久电影| 欧美国产第一页| 国内精品久久久| 亚洲成av人片在线观看香蕉| 欧美视频在线观看免费网址| 欧美一区二区大胆人体摄影专业网站| 久久99亚洲热视| 国产成人精品一区二区在线| 国产精品久久久久久亚洲影视| 亚洲精品720p| 91精品久久久久久| 久久99视频免费| 日韩欧美视频一区二区三区| 91精品美女在线| 国产精品精品国产| 亚洲电影在线观看| 91在线精品视频| 亚洲精品欧美一区二区三区| 欧美一级视频在线观看| 久久久午夜视频| 亚洲综合第一页| 最近中文字幕2019免费| 91免费观看网站| 亚洲国产私拍精品国模在线观看| 日韩av中文字幕在线播放| 亚洲视屏在线播放| 欧美性黄网官网| 国产91免费观看| 国产视频综合在线| 国产精品一区专区欧美日韩| 欧美日韩国产专区| 亚洲va国产va天堂va久久| 亚洲欧美在线第一页| 欧美三级xxx| 中文字幕成人精品久久不卡| 欧美激情精品久久久久久久变态| 国产精品久久久久影院日本| 欧美日韩亚洲系列| 日本午夜精品理论片a级appf发布| 韩国19禁主播vip福利视频| 国产伦精品免费视频| 欧美性猛交xxxx乱大交极品| 亚洲精品第一页| 日韩中文字幕视频在线观看| 国产日韩中文字幕| 欧美激情一区二区三区高清视频| 91po在线观看91精品国产性色| 亚洲男人天堂2019| 日韩av电影在线网| 久久91亚洲精品中文字幕| 庆余年2免费日韩剧观看大牛| 欧美国产日产韩国视频| 欧美视频免费在线| 日韩精品中文字幕在线播放| 亚洲国产中文字幕在线观看| 日韩欧美在线视频日韩欧美在线视频| 日韩亚洲精品视频| 日韩欧美在线视频日韩欧美在线视频| 国产精品美乳一区二区免费| 91在线免费看网站| 夜夜嗨av色一区二区不卡| 国产一区二区三区欧美| 亚洲一级片在线看| 国产精品揄拍一区二区| 国产欧美va欧美va香蕉在| 欧美日韩视频免费播放| 欧美放荡办公室videos4k| 日韩成人中文电影| 91在线精品视频| 日韩黄在线观看|