huffman
今天试着做了个Huffman,结果压缩算法被硬生生写成膨胀算法
我好蒻啊!!!!!!!!!!!!!!!
加密:
1 #include<bits/stdc++.h> 2 #include<windows.h> 3 #define ll long long 4 #define N 10000001 5 using namespace std; 6 int cnt; 7 struct node{ 8 int l,r,val; 9 char ch; 10 }hfm[N]; 11 12 struct cmp{bool operator()(int a,int b){return hfm[a].val>hfm[b].val;}}; 13 14 char a[128],b[128],str[N]; 15 int tohfm[256],len,root,cdl[256]; 16 bitset<8>code[256]; 17 bool apr[256]; 18 priority_queue<int,vector<int>,cmp>q; 19 20 void dfs(int x,int dep,int cd){ 21 if(hfm[x].ch){ 22 int ascii=(int)hfm[x].ch; 23 cdl[ascii]=dep; 24 for(int i=dep-1;i>=0;i--) 25 code[ascii][i]=cd&1,cd>>=1; 26 return; 27 } 28 dfs(hfm[x].l,dep+1,cd<<1); 29 dfs(hfm[x].r,dep+1,cd<<1|1); 30 } 31 32 void huffman(){ 33 for(int i=1;i<=cnt;i++)q.push(i); 34 while(q.size()>=2){ 35 int a,b,c; 36 a=q.top(),q.pop(); 37 b=q.top(),q.pop(); 38 c=++cnt; 39 hfm[c].l=a,hfm[c].r=b,hfm[c].val=hfm[a].val+hfm[b].val; 40 q.push(c); 41 } 42 dfs(root=cnt,0,0); 43 } 44 45 void Out(int x){ 46 char ch[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; 47 printf("%c%c",ch[x/16],ch[x%16]); 48 } 49 50 int main(){ 51 scanf("%s%s",a,b); 52 freopen(a,"r",stdin); 53 freopen(b,"w",stdout); 54 while(~scanf("%c",&str[++len])){ 55 int ascii=(int)str[len]; 56 if(!apr[ascii]) 57 tohfm[ascii]=++cnt,apr[ascii]=true,hfm[cnt].ch=str[len]; 58 hfm[tohfm[ascii]].val++; 59 } 60 int cnt1=cnt; 61 huffman(); 62 Out(cnt1); 63 for(int i=1;i<=cnt1;i++){ 64 int ascii=(int)hfm[i].ch; 65 Out(ascii); 66 int ans=1; 67 for(int j=0;j<cdl[ascii];j++)ans=ans<<1|code[ascii][j]; 68 Out(ans); 69 } 70 int tail=0,ans=0; 71 for(int i=1;i<=len;i++){ 72 int ascii=(int)str[i]; 73 for(int j=0;j<cdl[ascii];j++){ 74 tail++; 75 ans=ans<<1|code[ascii][j]; 76 if(tail==7){ 77 Out(ans); 78 tail=0,ans=0; 79 } 80 } 81 } 82 if(tail) 83 Out(ans<<(7-tail)); 84 return 0; 85 }
解密:
1 #include<bits/stdc++.h> 2 #include<windows.h> 3 #include<conio.h> 4 #define ll long long 5 #define N 100001 6 using namespace std; 7 char hfm[1024],a[128],b[128]; 8 int n; 9 10 int In(){ 11 int re=0; 12 char a,b; 13 if(!~scanf("%c%c",&a,&b))return -1; 14 re=(a<='9'?a-'0':a-'A'+10); 15 re=re<<4|(b<='9'?b-'0':b-'A'+10); 16 return re; 17 } 18 19 int main(){ 20 scanf("%s%s",a,b); 21 freopen(a,"r",stdin); 22 freopen(b,"w",stdout); 23 n=In(); 24 for(int i=1;i<=n;i++){ 25 int ch,code; 26 ch=In(); 27 code=In(); 28 hfm[code]=(char)ch; 29 // printf("%c : %d\n",ch,code); 30 } 31 int byte,last; 32 int val=1; 33 while(~(byte=In())){ 34 for(int i=6;i>=0;i--){ 35 val=val<<1|((byte&(1<<i))>>i); 36 if(hfm[val]){ 37 if(hfm[val]&(1<<7)) 38 if(!last)last=hfm[val]; 39 else printf("%s",last<<8|(hfm[val])),last=0; 40 else printf("%c",hfm[val]); 41 val=1; 42 } 43 } 44 } 45 return 0; 46 }
BUG很多,可行性很低,我很蒻
但是可以用来加密(雾)
其实就是模板改了一下
2018-12-12:
在11月份的的时候做出了真正的huffman压缩
今天突然想起发过这篇文章
于是来贴个代码
压缩:
1 #include<bits/stdc++.h> 2 #include<fstream> 3 #define ll long long 4 #define N 10000001 5 #define code(a,b) get(code[a],b) 6 #define Out(x,y) output.write((char*)&x,y) 7 using namespace std; 8 int cnt; 9 struct node{ 10 int l,r,val; 11 char ch; 12 }hfm[N]; 13 14 char a[128],b[128],str[N]; 15 int tohfm[512],len,root,cdl[512]; 16 int code[1024]; 17 bool apr[1024]; 18 19 struct cmp{bool operator()(int a,int b){return hfm[a].val>hfm[b].val;}}; 20 21 priority_queue<int,vector<int>,cmp>q; 22 23 void dfs(int x,int dep,int cd){ 24 if(!x)return; 25 if(hfm[x].ch){ 26 int ascii=hfm[x].ch; 27 cdl[ascii]=dep; 28 code[ascii]=cd; 29 return; 30 } 31 dfs(hfm[x].l,dep+1,cd<<1); 32 dfs(hfm[x].r,dep+1,cd<<1|1); 33 } 34 35 void huffman(){ 36 for(int i=1;i<=cnt;i++)q.push(i); 37 while(q.size()>=2){ 38 int a,b,c; 39 a=q.top(),q.pop(); 40 b=q.top(),q.pop(); 41 c=++cnt; 42 hfm[c].l=a,hfm[c].r=b,hfm[c].val=hfm[a].val+hfm[b].val; 43 q.push(c); 44 } 45 if(cnt==1)code[(unsigned)hfm[1].ch]=2,cdl[(unsigned)hfm[1].ch]=1; 46 else dfs((root=cnt),0,1); 47 } 48 49 int get(int a,int b){return (a&(1<<(8-b)))>>(8-b);} 50 51 int main(){ 52 scanf("%s%s",a,b); 53 ofstream output(b,ios::out|ios::binary); 54 FILE* file = fopen(a, "rb"); 55 fseek(file,0,SEEK_END); 56 len=ftell(file); 57 fclose(file); 58 ifstream input(a,ios::in|ios::binary); 59 input.read((char*)&str,len); 60 for(int i=0;i<len;i++){ 61 if(!apr[(int)str[i]]) 62 tohfm[(int)str[i]]=++cnt,apr[(int)str[i]]=true,hfm[cnt].ch=str[i]; 63 hfm[tohfm[(int)str[i]]].val++; 64 } 65 int Len=len; 66 input.close(); 67 int cnt1=cnt; 68 huffman(); 69 Out(cnt1,4); 70 Out(Len,4); 71 printf("%d %d\n",cnt1,Len); 72 for(int i=1;i<=cnt1;i++){ 73 int ascii=(int)hfm[i].ch; 74 Out(hfm[i].ch,1); 75 printf("%c %d ",ascii,cdl[ascii]); 76 int ans=code[ascii]; 77 Out(ans,1); 78 for(int j=1;j<=8;j++)printf("%d",code(ascii,j)); 79 puts(""); 80 } 81 int tail=0,ans=0; 82 for(int i=0;i<Len;i++){ 83 int ascii=(int)str[i]; 84 //printf("%d ",code[ascii]); 85 for(int j=8-cdl[ascii]+1;j<=8;j++){ 86 tail++; 87 ans=ans<<1|code(ascii,j); 88 if(tail==8){ 89 for(int j=1;j<=8;j++)printf("%d",get(ans,j)); 90 //printf("%d ",ans); 91 Out(ans,1); 92 tail=0,ans=0; 93 } 94 } 95 } 96 puts(""); 97 if(tail)ans<<=(8-tail),Out(ans,1); 98 output.close(); 99 return 0; 100 } 101 /* 102 1.txt 103 2.txt 104 */
解压:
1 #include<bits/stdc++.h> 2 #include<fstream> 3 #define ll long long 4 #define N 10000001 5 #define In(x,y) input.read((char*)&x,y) 6 #define Out(x,y) output.write((char*)&x,y) 7 using namespace std; 8 char a[128],b[128],hfm[(1<<16)-1]; 9 int n,len; 10 int get(int a,int b){return (a&(1<<(8-b)))>>(8-b);} 11 int main(){ 12 scanf("%s%s",a,b); 13 ifstream input(a,ios::in|ios::binary); 14 ofstream output(b,ios::out|ios::binary); 15 In(n,4),In(len,4); 16 printf("N=%d Len=%d\n",n,len); 17 for(int i=1;i<=n;i++){ 18 char ch; 19 int code=0; 20 In(ch,1),In(code,1); 21 printf("%c : %d\n",ch,(int)code); 22 hfm[(int)code]=ch; 23 } 24 int byte; 25 int val=1; 26 while(len){ 27 byte=0; 28 In(byte,1); 29 for(int i=1;i<=8;i++){ 30 val=val<<1|get(byte,i); 31 if(hfm[val]){ 32 len--; 33 Out(hfm[val],1); 34 printf("%c",hfm[val]); 35 val=1; 36 } 37 if(!len)break; 38 } 39 } 40 return 0; 41 }