进阶实验4-3.5 哈夫曼编码 (30分)-最优二叉树
解题思路:
由于哈夫曼树并不唯一,但哈夫曼树的带权路径长度 WPL是相同且是最优,
故,利用哈夫曼算法求出WPL,再计算每套编码的WPL,如果WPL相同,则判断各字符编码是否是其他字符编码的前缀
#include <stdio.h> #include <string.h> #define INF 0x3f3f3f3f typedef struct { int weight,flag; char name; } HashTree; int add_Hash(HashTree H[],int start,int end) { int MIN=INF; int fmin=start,smin=start; int i; for(i=start; i<end; i++) { if(H[i].flag==0&&H[i].weight<MIN) { MIN=H[i].weight; fmin=i; } } H[fmin].flag=1; MIN=INF; for(i=start; i<end; i++) { if(H[i].flag==0&&H[i].weight<MIN) { MIN=H[i].weight; smin=i; } } H[smin].flag=1; int weight=H[smin].weight+H[fmin].weight; H[end].weight=weight; return weight; } int main() { int n; scanf("%d",&n); int i; char c; int x; HashTree H[2*n]; memset(H,0,sizeof(H)); for(i=0; i<n; i++) { scanf("\n%c%d",&H[i].name,&H[i].weight); H[i].flag=0; } i=n; int weight=0; while(i!=2*n-1) { weight+=add_Hash(H,0,i); i++; } int m,j,k,l; scanf("%d",&m); char str[m][64]; char name; for(k=0; k<m; k++) { int sum=0; for(j=0; j<n; j++) { scanf("\n%c%s",&name,str[j]); sum+=strlen(str[j])*H[j].weight; } if(sum==weight) { int flag=0; for(j=0; j<n; j++) { for(l=0; l<n; l++) { if(j!=l) { if(strstr(str[l],str[j])==&str[l][0]) { //查找字符串,如果找到了并且是前缀,就标记为No了 flag=1; break; } } } if(flag==1)break; } if(flag==1)printf("No\n"); else printf("Yes\n"); } else printf("No\n"); } return 0; }
勤能补拙,熟能生巧