5-9 Huffman Codes
来源:互联网 发布:mac osx yosemite.vdi 编辑:程序博客网 时间:2024/06/04 23:27
点击打开链接
符合两个要求就可以判断该树是否满足要求
判断输入的编码是否符合要求(1、编码长度与Huffman编码长度相同 2、前缀编码)
首先想到的避免建一棵哈弗曼树,是用一个结构体node来保存学生提交的节点的编码
但估计在判断前缀编码时会超时(N<=63 ,两层for循环),不能拿满分
#include<stdio.h>#include<stdlib.h>#include<iostream>#include<queue>#include<algorithm>#include<map>#include<vector>#include<cstring>#include<math.h>#include<stack>using namespace std;判断输入的编码是否符合要求(1、编码长度与Huffman编码长度相同 2、前缀编码)int N;struct node{ string s; //学生提交的节点的编码 int Count;//节点的频率}p[80];map<char,int >ha;//频率priority_queue<int ,vector<int>,greater<int> > q;//从小到大排bool check(){ int i,j; for( i=0;i<N;i++) { string temp=p[i].s.substr(0,p[i].s.length()); for( j=0;j<N;j++) { if(i==j) continue; else { if(temp==p[j].s.substr(0,p[i].s.length())) break; } } if(j<N) return false; } return true;}int main(){ char c; scanf("%d",&N); int wpl=0; for(int i=0;i<N;i++) { //scanf("%c ",&c); cin>>c; scanf("%d",&ha[c]);//记录每个节点的频率 q.push(ha[c]); } int cur; while(!q.empty()) { cur=q.top(); q.pop(); if(q.empty())//最后一次不用加 { break; } cur+=q.top(); q.pop(); wpl+=cur; q.push(cur); } int num; scanf("%d",&num); while(num--) { int sum=0; int flag=0; for(int i=0;i<N;i++) { cin>>c; p[i].Count=ha[c]; cin>>p[i].s; sum+=p[i].Count * p[i].s.length(); if(p[i].s.length() > N-1) { flag=1; } } if(flag) { cout<<"No"<<endl; continue; } else if(check() && sum == wpl) cout<<"Yes"<<endl; else cout<<"No"<<endl; }}
所以改用一个最小堆来实现这个哈弗曼树,定义 struct treenode 为树的节点,定义struct heapnode 为堆,创立一个最小堆,先取出一个最小值的节点为左节点 ,在取一个最小值为右节点,然后把左右节点的和的节点再放入最小堆,循环反复,就可以生成哈弗曼树。然后再判定一下前缀码,即当在一个图中,遍历到这一节点时,该节点不能曾经被遍历过,然后遍历到最后一个节点时,该节点不能再有左右子节点。即所有存信息的节点为叶子节点。
#include<stdio.h>#include<stdlib.h>#include<iostream>#include<queue>#include<algorithm>#include<map>#include<vector>#include<cstring>#include<math.h>#include<stack>#include <string>using namespace std;#define maxnum 64struct treenode//树的节点{ int weight=0; treenode *left=NULL; treenode *right=NULL;};struct heapnode//堆{ treenode data[maxnum]; int Size=0;};heapnode* createheap(int N)//创建一个小根堆{ heapnode *H= new(heapnode); H->data[0].weight= -1; return H;//返回指向小根堆堆首的元素}treenode* deletemin(heapnode *H)//传入指向小根堆堆首的元素,从堆中删除一个元素{ int parent=0,child=0; treenode temp; treenode *minitem= new(treenode); *minitem = H->data[1]; temp= (H->data[(H->Size)--]); for(parent=1; parent*2 <= H->Size ; parent=child) { child= parent*2; if((child !=H->Size ) && (H->data[child].weight) > (H->data[child+1].weight)) { child++; } if((temp.weight) <= H->data[child].weight) { break; } else { H->data[parent] = H->data[child]; } } H->data[parent]=temp; return minitem;//返回指向最小堆的头节点的指针}void Insert(heapnode *H,treenode *item){ int i=0; i=++(H->Size); for( ; H->data[i/2].weight > item->weight ;i/=2) { H->data[i]= H->data[i/2]; } H->data[i]= *item;}heapnode* readdata(int N,heapnode *H,int A[]){ char s='\0'; int value= 0; for(int i=0;i<N;i++) { cin>>s; cin>>value; A[i]= value; treenode *T= new(treenode); T->weight= value; Insert(H,T); } return H;}treenode* huffman(heapnode *H){ treenode *T=NULL; int num= H->Size; for(int i=0;i<num-1;i++) { T=new(treenode); T->left= deletemin(H); T->right= deletemin(H); T->weight= T->left->weight + T->right->weight; Insert(H,T); } T=deletemin(H); return T;}int wpl(treenode *T,int depth)//depth代表深度 , 此函数计算wpl{ if(T->left==NULL && T->right==NULL) { return depth * T->weight; } else { return ( wpl(T->left,depth+1) + wpl(T->right,depth+1) ); }}struct JNode{ int Flag=0; JNode *Left=NULL; JNode *Right=NULL;};bool Judge(string s,JNode *j)//判断该次编码能否符合前缀编码的要求{ int i=0; for( ; i<s.length() ; i++) { if(s[i]== '0') { if( j->Left==NULL )//如果左边不存在节点 { JNode *j_1=new(JNode); j->Left=j_1; } else { if(j->Left->Flag==1) { return false; } } j=j->Left; } else { if(j->Right==NULL) { JNode *j_1=new(JNode); j->Right=j_1; } else { if(j->Right->Flag==1) { return false; } } j=j->Right; } } j->Flag=1; if(j->Left==NULL && j->Right==NULL ) { return true; } else { return false; }}int main(){ int n=0,N=0; cin>>N; heapnode *H= createheap(N);//创立最小堆H int Value[maxnum]={}; H=readdata(N,H,Value); treenode *T= huffman(H);//建立一棵哈弗曼树T int codelen=wpl(T,0); cin>>n; string temp="\0"; char c='\0'; bool result=false; for(int i=0;i<n;i++) { int Count=0,flag=0; JNode *j=new(JNode); for(int k=0;k<N;k++) { cin>>c>>temp; Count+= temp.length() * Value[k]; if(!flag) { result=Judge(temp,j); if(!result) { flag=1; } } } delete j; if(result && Count==codelen) { cout<<"Yes"<<endl; } else { cout<<"No"<<endl; } }}
阅读全文
0 0
- 5-9 Huffman Codes
- 5-9 Huffman Codes (30分)
- 05-树9 Huffman Codes
- 05-树9 Huffman Codes
- 05-树9 Huffman Codes
- 05-树9 Huffman Codes
- 05-树9 Huffman Codes
- 05-树9 Huffman Codes
- 05-树9 Huffman Codes
- Huffman codes
- Huffman Codes
- Huffman Codes
- Huffman Codes
- Huffman Codes
- Huffman codes
- 05-树9 Huffman Codes (30分)
- 05-树9 Huffman Codes (30分)
- 05-树9 Huffman Codes (30分)
- 三种实现下拉菜单的方式
- TabLayout、ViewPager与Fragment
- 【Android】当关闭通知权限后无法显示Toast的解决方案V2.0
- Android ProgressBar 之源码解析及扩展应用!
- S5700telnet配置及清除console密码举例
- 5-9 Huffman Codes
- C#读取excel文件数据丢失问题
- 浅谈团队项目管理
- Android Butter Knife 框架——最好用的View注入
- 从输入网址到显示网页的全过程分析
- WEB前端使用 webpack + reack 搭建框架 02 本地服务 与 热替换(react-hot-loader)
- python3脚本使用sql loader批量导入字节文件并二次处理
- Python3 socketserver 实现局域网通信
- spark企业经典案例之手机app流量统计