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;
    #define maxn 70
    int N,codelen,cnt1,cnt2,w[maxn];
    char ch[maxn];
    typedef struct TreeNode* Tree;
    struct TreeNode{
        int weight;
        Tree Left,Right;
    };
    typedef struct HeapNode* Heap;
    struct HeapNode{
        struct TreeNode Data[maxn];
        int size;
    };
    
    Tree creatTree(){
          Tree T;
          T = new struct TreeNode;
          T->weight = 0;
          T->Left = T->Right = NULL;
          return T;
    }
    
    Heap creatHeap(){
        Heap H;
        H = new struct HeapNode;
        H->Data[0].weight = -1;
        H->size = 0;
        return H;
    }
    
    void Insert(Heap H,struct 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 Delete(Heap H){
        int child,parent;
        struct TreeNode Temp = H->Data[H->size--];
        Tree T = creatTree();
        *T = H->Data[1];
        for(parent = 1; 2 * parent <= H->size; parent = child){
            child = 2 * parent;
            if(child < H->size && H->Data[child].weight > H->Data[child+1].weight)
            child++;
            if(H->Data[child].weight > Temp.weight) break;
            H->Data[parent] = H->Data[child];
        }
        H->Data[parent] = Temp;
        return T;
    }
    
    Tree Huffman(Heap H){
        Tree T = creatTree();
        while(H->size != 1){
            T->Left = Delete(H);
            T->Right = Delete(H);
            T->weight = T->Right->weight + T->Right->weight;
            Insert(H,*T);
        }
        T = Delete(H);
        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);
    }
    
    void JudgeTree(Tree T){
        if(T){
            if(T->Right && T->Left) cnt2++;
            else if(!T->Left && !T->Right) cnt1++;
            else cnt1 = 0;
            JudgeTree(T->Left);
            JudgeTree(T->Right);
        }
    }
    
    int Judge(){
        int i,j,wgh,flag = 1;;
        char s1[maxn],s2[maxn];
        Tree T = creatTree(), pt = NULL;
        for(i = 0; i < N; i++){
            cin >> s1 >> s2;
            if(strlen(s2) > N) return 0;
            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 = 0;
                if(!s2[j+1]){
                    if(pt->Left || pt->Right) flag = 0;
                    else pt->weight = wgh;
                }
            }
        }
        if(flag == 0) return 0;
        cnt1 = cnt2 = 0;
        JudgeTree(T);
        if(cnt1 != cnt2 + 1) return 0;
        if(codelen == WPL(T,0)) return 1;
        else return 0;
    }
    
    int main(){
        int i,n;
        Tree T;
        Heap H;
        T = creatTree();
        H = creatHeap();
        cin >> N;
        for(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 >> n;
        while(n--){
            if(Judge()) cout<< "Yes" << endl;
            else cout << "No" << endl;
        }
        return 0;
    }
  • 相关阅读:
    Making your first driver
    注册表与盘符(转victor888文章 )
    电脑Win7如何取得文件管理所有权(提供各种GHOST版本的Windows)
    可拖动的DIV
    IE Javascript 进阶调试
    优化性能
    命令模式
    MVC 4 结合jquery.uploadify 上传实例
    IIS处理并发请求时出现的问题及解决
    Spring3.2 + Hibernate4.2
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/9968980.html
Copyright © 2011-2022 走看看