题意:不能是前缀码而且是哈弗曼算法算出的最优编码长度的编码就行
基本思路:先根据所给字符和频率构造哈夫曼树,算出最优wpl编码数sum;后面每一套验证是否有前缀码和是否wpl=sum;
#include<stdio.h>
#include<malloc.h>
#include<map>
using namespace std;
typedef struct node {
char le;
int fre;
struct node* left;
struct node* right;
} *pnode;
int msize = 0, sum = 0,sum1=0, n;//msize为mdui的长度;
pnode root;
pnode crtree(pnode mroot,char k[],int n,int i);//验证代码时构造树来判断
int flag = 0;//树是否有前缀码的判断标志
pnode mdui[10000];
int judge(char m);//判断是否为所给字符;
void insert(pnode h);//插入堆函数
pnode sele();//删除堆函数
int calculate(pnode h, int cnt, int l);//计算前缀码函数
map<char, int>t; //最简单的map应用,储存字符对应的频率
char lett[65];//储存给的字符
char code[65][65];//储存验证的编码
int main()
{
mdui[0] =(pnode)malloc(sizeof(sizeof(struct node)));
mdui[0]->fre = -1;;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
pnode dno=(pnode)malloc(sizeof(struct node));
getchar();
scanf("%c %d", &dno->le, &dno->fre);
lett[i] = dno->le;
t[dno->le] = dno->fre;
dno->left = dno->right = NULL;
insert(dno);
}
for (int i = 0; i < n - 1; i++) {
pnode dno1 = sele(), dno2= sele();
pnode dno3 = (pnode)malloc(sizeof(struct node));
dno3->fre = dno1->fre + dno2->fre;
dno3->left = dno1; dno3->right = dno2;
dno3->le = '#';
insert(dno3);
}
sum=calculate(mdui[1], -1,0);
int m; scanf("%d", &m);
while (m--) {
flag = 0;
pnode proot = NULL;
for (int j = 0; j < n; j++) {
getchar(); getchar(); getchar();
scanf("%s", code[j]);
}
for (int i = 0; i < n; i++) {
proot = crtree(proot,code[i], 0, i);
}
sum1 = calculate(proot, -1, 0);
if (flag != 1) if (sum1 ==sum) printf("Yes"); else printf("No");
else printf("No");
if (m != 0) printf("\n");
}
return 0;
}
int judge(char m) {
if (m<= '9' && m >= '0' || m <= 'z' && m >= 'a' || m >= 'A' && m <= 'Z'||m=='_') {
return 1;
}
else return 0;
}
void insert(pnode h) {
int i = ++msize;
mdui[i] = (pnode)malloc(sizeof(struct node));
mdui[i]->left = mdui[i]->right = NULL;
for (; mdui[i / 2]->fre > h->fre; i = i / 2) {
mdui[i] = mdui[i / 2];
}
mdui[i] = h;
}
pnode sele() {
struct node* root = (pnode)malloc(sizeof(struct node));
root->left = root->right = NULL;
root = mdui[1];
pnode temp = mdui[msize--];
int parent = 1,child;
for (; parent * 2 <= msize; parent = child) {
child = parent * 2;
if (child + 1 < msize && mdui[child + 1]->fre < mdui[child]->fre) child++;
if (temp->fre < mdui[child]->fre) break;
else {
mdui[parent] = mdui[child];
parent = child;
}
}
mdui[parent] = temp;
return root;
}
int calculate(pnode h, int cnt, int l) {
cnt++; l = 0;
if (judge(h->le) == 1) {
l= t[h->le] * cnt;
}
if (h->left) l+=calculate(h->left, cnt,0);
if (h->right) l+=calculate(h->right, cnt,0);
return l;
}
pnode crtree(pnode mroot,char k[], int n,int i) {
if (k[n] == '\0') {
if (mroot != NULL) flag = 1;
else {
mroot = (pnode)malloc(sizeof(struct node));
mroot->le = lett[i];
mroot->fre = t[lett[i]];
mroot->left = mroot->right = NULL;
}
}
else {
if (mroot == NULL) {
mroot = (pnode)malloc(sizeof(struct node));
mroot->le = '#';
mroot->left = mroot->right = NULL;
}
if (k[n] == '0') mroot->left=crtree(mroot->left, k, n + 1, i);
else mroot->right=crtree(mroot->right, k, n + 1, i);
}
return mroot;
}