进阶实验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("
%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("
%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
");
            else printf("Yes
");
        } else
            printf("No
");
    }

    return 0;
}
原文地址:https://www.cnblogs.com/snzhong/p/12620545.html