题意:给出字符和频率,检查学生的答案是不是最优解
输入输出:
主要思路:读入第一行数据,建立哈夫曼树,计算最优编码长度,然后读入学生数据,先计算编码长度,再检查是否符合前缀码。
但在视频中给出的建哈夫曼树的方法(如下)
使用了堆,在前面堆的章节中,元素使用数组存储,但这里函数insert和delete都返回指针,所以建立最小堆要使用结构体指针数组
堆的插入和删除如下(dt[] 是结构体指针数组,是最小堆)
然后按照视频的方法建造树
完整代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,heapsize;
map<char,int>mm;
bool f2;
struct data{
char a;
string b;
};
data d1[64];//d1是读入的学生的数据
typedef struct node* ht;
struct node{
char s;
int w;
ht l,r;
};
ht dt[64],d2[64];//使用结构体指针数组建造最小堆 ,d2是读入数据,dt是堆
void insert(ht t,int i){
for(;i>1&&dt[i/2]->w > t->w ;i/=2){
dt[i] = dt[i/2];
}
dt[i] = t;
}
ht d(){ //删除堆元素 ,返回所删除的指针
ht t = dt[1],temp = dt[heapsize--];
int p,c;
for(p = 1;p*2<=heapsize;p = c){
c = p*2;
if((c!=heapsize) && (dt[c]->w >dt[c+1]->w)){
c++;
}
if(temp->w <=dt[c]->w )break;
else{
dt[p] = dt[c];
}
}
dt[p] = temp;
return t;
}
ht h(){//构建哈夫曼树
ht T;
for(int i = 1;i<n;i++){
T = (ht)malloc( sizeof( struct node ) );
T->l = d();
T->r = d();
T->w = T->l->w +T->r->w ;
insert(T,++heapsize);
}
T = d();
return T;
}
int getsum(ht H,int i){//i是层数,从0开始
if(!H->l &&!H->r ){
return i*H->w ;
}else{
return getsum(H->l ,i+1)+getsum(H->r ,i+1);
}
}
void check(){//根据视频方法,建树判断
ht head,t;
t = (ht)malloc(sizeof(struct node));
t->w = 0;
t->l = t->r = NULL;
head = t;//保存树根
for(int i = 1;i<=n && f2;i++){
t = head;//指向树根
string s = d1[i].b ;
for(int j = 0;j<s.size()-1;j++){
if(t->w ){//非前缀码
f2 = false;
break;
}
if(s[j]=='0'){
if(!t->l ){
ht tt;
tt = (ht)malloc(sizeof(struct node));
tt->l = tt->r = NULL;
tt->w =0;
t->l = tt;
}
t = t->l ;
}
if(s[j]=='1'){
if(!t->r ){
ht tt;
tt = (ht)malloc(sizeof(struct node));
tt->r = tt->l =NULL;
tt->w = 0;
t->r = tt;
}
t = t->r ;
}
}//后面进行叶子节点的判断
if(s[s.size()-1]=='0'){
if(t->l ){
f2 = false;
}else{
ht tt;
tt = (ht)malloc(sizeof(struct node));
tt->l = tt->r = NULL;
tt->w = 1;
t->l = tt;
}
}
if(s[s.size()-1]=='1'){
if(t->r ){
f2 = false;
}else{
ht tt;
tt = (ht)malloc(sizeof(struct node));
tt->l = tt->r = NULL;
tt->w = 1;
t->r = tt;
}
}
}
}
int main(){
cin>>n;
for(int i = 1;i<=n;i++){
char k;
int l;
cin>>k>>l;
mm[k] = l;
d2[i] = (ht)malloc(sizeof(struct node));
dt[i] = (ht)malloc(sizeof(struct node));
d2[i]->s = k;
d2[i]->w = l;
d2[i]->r = d2[i]->l =NULL;
insert(d2[i],i);
}
heapsize = n;
ht H = h();
int sum = 0;
sum = getsum(H,0);//计算最优编码长度
cin>>m;
bool f1 = false;//判断是否输出换行
while(m--){
f2 = true;
int sumstu = 0;
for(int i = 1;i<=n;i++){
char k;
string l;
cin>>k>>l;
d1[i].a = k;
d1[i].b = l;
sumstu+=l.length()*mm[k];
}
if(sumstu != sum){
f2 = false;
}
if(f2){1
check();
}
if(f1){
cout<<endl;
}else f1 = true;
if(f2)cout<<"Yes";
else cout<<"No";
}
return 0;
}