zoukankan      html  css  js  c++  java
  • 7-1 Huffman Codes (30 分)

    7-1 Huffman Codes (30 分)(谷歌翻译的)

    1953年,David A. Huffman发表了他的论文“构建最小冗余码的方法”,因此在计算机科学史上印刷了他的名字。作为给霍夫曼代码提出期末考试问题的教授,我遇到了一个大问题:霍夫曼代码并不是唯一的。例如,给定一个字符串“aaaxuaxz”,我们可以观察到字符“a”,“x”,“u”和“z”的频率分别为4,2,1和1。我们可以将符号编码为{'a'= 0,'x'= 10,'u'= 110,'z'= 111},或者换句话为{'a'= 1,'x'= 01 ,'u'= 001,'z'= 000},都将字符串压缩为14位。另一组代码可以给出{'a'= 0,'x'= 11,'u'= 100,'z'= 101},但{'a'= 0,

    输入规格:

    每个输入文件包含一个测试用例。对于每种情况,第一行给出一个整数N≤ Ñ ≤ 3),再其次是一个包含所有的线N个不同的字符及其频率采用以下格式:

    c[1] f[1] c[2] f[2] ... c[N] f[N]
    

      其中c[i]是从{'0' - '9','a' - 'z','A' - 'Z','_'}中选择的字符,并且f[i]c[i]并且是不超过1000的整数的频率。下一行给出正整数M≤ 0),则接着M学生提交。每个学生提交的内容包括N行,每行格式:

    c[i] code[i]
    

      其中c[i]i-th字符,code[i]是一个非空字符串,不超过63'0和'1'。

    输出规格:

    对于每个测试用例,如果学生的提交正确,则在每行打印“是”,否则打印“否”。

    注意:最优解不一定是由霍夫曼算法生成的。任何代码长度最佳的前缀代码都被认为是正确的。

    样本输入:

    7
    A 1 B 1 C 1 D 3 E 3 F 6 G 6
    4
    A 00000
    B 00001
    C 0001
    D 001
    E 01
    F 10
    G 11
    A 01010
    B 01011
    C 0100
    D 011
    E 10
    F 11
    G 00
    A 000
    B 001
    C 010
    D 011
    E 100
    F 101
    G 110
    A 00000
    B 00001
    C 0001
    D 001
    E 00
    F 10
    G 11
    

      

    样本输出:

    Yes
    Yes
    No
    No
    

      

    #include<stdio.h>
    #include<stdlib.h>
    #include<malloc.h>
    #include<string.h>
    typedef struct HFTNode
    {
        char Data;
        int Parent;
        int Lchild;
        int Rchild;
        int Weight;
    }HFTNode, *HFTree;
    typedef struct CNode
    {
        char Data;
        char Code[100];
    }CNode;
    HFTree T;
    void AddNode(int N)
    {
        int min1 = 0, min2 = 0;
        for(int i=1; i<N; i++){//找到两个没父母的节点
            if(T[i].Parent == 0 && min1 == 0)
                min1 = i;
            else if(T[i].Parent == 0 && min1 != 0)
                min2 = i;
        }
        if(T[min1].Weight > T[min2].Weight){
            int temp = min1;
            min1 = min2;
            min2 = temp;
        }
        for(int i=1; i<N; i++){//找到两个没父母的最小节点
            if(T[i].Parent == 0 && T[i].Weight < T[min1].Weight){
                min2 = min1;
                min1 = i;
            }
            else if(T[i].Parent == 0 && T[i].Weight < T[min2].Weight && i!=min1 )
                min2 = i;
        }
        T[N].Weight = T[min1].Weight + T[min2].Weight;
        T[N].Lchild = min1;
        T[N].Rchild = min2;
        T[N].Parent = 0;
        T[min1].Parent = N;
        T[min2].Parent = N;
    }
    int JuChild(int m1, int m2, CNode *Code)
    {
        int len = strlen(Code[m1].Code);
        int flag = 0;
        for(int i=0; i<len; i++){
            if(Code[m1].Code[i] != Code[m2].Code[i])//存在不相等的则赋1
                flag = 1;
        }
        if(flag == 0)//说明是子序列
            return 1;
        else
            return 0;
    }
    int main()
    {
        int N, M, Weight=0;
        scanf("%d", &N);getchar();
        T = (HFTNode*)malloc(sizeof(HFTNode)*(2*N));
        for(int i=1; i<=N; i++){
            scanf("%c %d", &T[i].Data, &T[i].Weight);getchar();
            T[i].Parent = 0;
            T[i].Lchild = 0;
            T[i].Rchild = 0;
        }
        for(int i=N+1; i<2*N; i++){//带权路径为非叶节点权值之和
            AddNode(i);
            Weight += T[i].Weight;
    
        }
        scanf("%d", &M);
        for(int i=0; i<M; i++){
            CNode Code[100];
            int weight = 0;
            for(int j=1; j<=N; j++){
                scanf("%c%*c%s", &Code[j].Data, &Code[j].Code);
                weight += T[j].Weight * strlen(Code[j].Code);
            }
            if(weight != Weight)//带权路径不一致
                printf("No
    ");
            else{
                    int flag = 1;
                for(int j=N; j>=1 && flag; j--){//判断某个序列是否是另一个编码的子序列
                    for(int i=1; i<j; i++){
                        int is = JuChild(j, i, Code);
                        if(is){
                            printf("No
    ");
                            flag = 0;
                            break;
                        }
                    }
                }
                if(flag)
                    printf("Yes
    ");
            }
    
        }
    }
    

      

  • 相关阅读:
    *args和**kwargs
    事件驱动模型
    同步异步和阻塞非阻塞
    多进程和多线程
    认识tornado(五)
    认识tornado(四)
    认识tornado(三)
    [GO]使用select实现超时
    [GO]使用select实现斐波那契
    [GO]ticker的使用
  • 原文地址:https://www.cnblogs.com/Jie-Fei/p/10158522.html
Copyright © 2011-2022 走看看