zoukankan      html  css  js  c++  java
  • 05-树9 Huffman Codes (30 分)

    In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Redundancy Codes", and hence printed his name in the history of computer science. As a professor who gives the final exam problem on Huffman codes, I am encountering a big problem: the Huffman codes are NOT unique. For example, given a string "aaaxuaxz", we can observe that the frequencies of the characters 'a', 'x', 'u' and 'z' are 4, 2, 1 and 1, respectively. We may either encode the symbols as {'a'=0, 'x'=10, 'u'=110, 'z'=111}, or in another way as {'a'=1, 'x'=01, 'u'=001, 'z'=000}, both compress the string into 14 bits. Another set of code can be given as {'a'=0, 'x'=11, 'u'=100, 'z'=101}, but {'a'=0, 'x'=01, 'u'=011, 'z'=001} is NOT correct since "aaaxuaxz" and "aazuaxax" can both be decoded from the code 00001011001001. The students are submitting all kinds of codes, and I need a computer program to help me determine which ones are correct and which ones are not.

    Input Specification:

    Each input file contains one test case. For each case, the first line gives an integer N (2), then followed by a line that contains all the N distinct characters and their frequencies in the following format:

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

    where c[i] is a character chosen from {'0' - '9', 'a' - 'z', 'A' - 'Z', '_'}, and f[i] is the frequency of c[i] and is an integer no more than 1000. The next line gives a positive integer M (≤), then followed by M student submissions. Each student submission consists of N lines, each in the format:

    c[i] code[i]
    

    where c[i] is the i-th character and code[i] is an non-empty string of no more than 63 '0's and '1's.

    Output Specification:

    For each test case, print in each line either "Yes" if the student's submission is correct, or "No" if not.

    Note: The optimal solution is not necessarily generated by Huffman algorithm. Any prefix code with code length being optimal is considered correct.

    Sample Input:

    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
    

    Sample Output:

    Yes
    Yes
    No
    No
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int maxn = 1010;
    
    int n,m;
    int wgh;
    int cnt1,cnt2;
    int w[maxn];
    char ch[maxn];
    int codelen;
    
    typedef struct TreeNode* Tree;
    struct TreeNode{
        int weight;
        Tree Left,Right;
    };
    typedef struct HeapNode* Heap;
    struct HeapNode{
        TreeNode Data[maxn];
        int size;
    };
    
    Tree creatTree();
    Heap creatHeap();
    void Insert(Heap H,TreeNode T);
    Tree Delete(Heap H);
    Tree Huffman(Heap H);
    int WPL(Tree T,int depth);
    void JudgeTree(Tree T);
    bool Judge();
    
    int main(){
        cin >> n;
        
        Tree T = creatTree();
        Heap H = creatHeap();
        
        for(int i = 0; i < n; i++){
            getchar();
            cin >> ch[i] >> w[i];
            H->Data[H->size].Left = H->Data[H->size].Right = NULL;
            T->weight = w[i];
            Insert(H,*T);
        }
         
         T = Huffman(H);
         
         codelen = WPL(T,0);
         cin >> m;
         while(m--){
             if(Judge()) printf("Yes
    ");
             else printf("No
    ");
         }
         
        return 0;
    }
    
    Tree creatTree(){
        Tree T = new TreeNode;
        T->weight = 0;
        T->Left = T->Right = NULL;
        return T;
    }
    
    Heap creatHeap(){
        Heap H = new HeapNode;
        H->Data[0].weight = -1;
        H->size = 0;
        return H;
    }
    
    void Insert(Heap H,TreeNode T){
        int i = ++H->size;
        for(;T.weight < H->Data[i/2].weight; i /= 2)
             H->Data[i] = H->Data[i/2];
        H->Data[i] = T;
    } 
    
    Tree Huffman(Heap H){
        Tree T = creatTree();
        while(H->size != 1){
            T->Left = Delete(H);
            T->Right = Delete(H);
            T->weight =  T->Left->weight + T->Right->weight;
            Insert(H,*T);
        }
        T = Delete(H);
        return T;
    }
    
    Tree Delete(Heap H){
        int child,parent;
        TreeNode temp = H->Data[H->size--];
        Tree T = creatTree();
        *T = H->Data[1];
        for(parent = 1; 2 * parent <= H->size; parent = child){
            child = parent * 2;
            if(child < H->size && H->Data[child+1].weight < H->Data[child].weight)
                     child++;
            if(H->Data[child].weight > temp.weight) break;
             H->Data[parent] = H->Data[child];
        }
        H->Data[parent] = temp;
        return T;
    }
    
    int WPL(Tree T,int depth){
        if(!T->Left && ! T->Right) return (depth*T->weight);
        else return WPL(T->Left,depth+1) + WPL(T->Right,depth+1);
    }
    
    bool Judge(){
        char s1[maxn],s2[maxn];
        bool flag = true;
        Tree T = creatTree();
        Tree pt = NULL;
        for(int i = 0; i < n; i++){
            cin >> s1 >> s2;
            if(strlen(s2) > n) return 0;
            int j;
            for(j = 0; s1[0] != ch[j];j++);
            wgh = w[j];
            pt = T;
            for(j = 0; s2[j]; j++){
                if(s2[j] == '0'){
                    if(!pt->Left) pt->Left = creatTree();
                    pt = pt->Left;
                }
                if(s2[j] == '1'){
                    if(!pt->Right) pt->Right = creatTree();
                    pt = pt->Right; 
                }
                if(pt->weight) flag = false;
                if(!s2[j+1]){
                    if(pt->Left || pt->Right) flag = false;
                    else pt->weight = wgh;
                }
            }
        }
        if(!flag) return 0;
        cnt1 = cnt2 = 0;
        JudgeTree(T);
        if(cnt1 != cnt2 + 1) return 0;
        if(codelen == WPL(T,0)) return 1;
        else return 0;
    }
    
    void JudgeTree(Tree T){
        if(T){
            if(T->Right&&T->Left) cnt2++;
            else if(!T->Right && !T->Left) cnt1++;
            else cnt1 = 0;
            JudgeTree(T->Left);
            JudgeTree(T->Right);
        }
    }
  • 相关阅读:
    SQL Server ->> 生成代码把表字段从NULL改为NOT NULL
    Hadoop ->> MapReduce编程模型
    SQL Server ->> 建立linked server到Azure SQL Server
    SQL Server ->> 存储过程sp_rename重命名数据对象
    SQL Server ->> CLR存储过程枚举目录文件并返回结果集
    SQL Server ->> 查看SQL Server备份历史
    SQL Server ->> 生成时间类型的Partition Function和Partition Scheme代码
    SQL Server ->> CLR编程问题汇总
    Hadoop ->> Name node/Data node和Job tracker/Task tracker的区别
    Hadoop ->> Hadoop是什么?
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/10763317.html
Copyright © 2011-2022 走看看