• 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 <= N <= 63), 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;
    
    typedef struct TreeNode* Tree;
    struct TreeNode
    {
        Tree left,right;
        int weight;
    };
    
    typedef struct HeapNode* Heap;
    struct HeapNode
    {
        TreeNode Data[maxn];
        int size;
    };
    
    int n,m;
    int w[maxn];
    char ch[maxn];
    int codelen;
    int cnt2,cnt0;
    
    Tree creatTree();
    Heap creatHeap();
    void Insert(Heap H, TreeNode T);
    Tree Huffman(Heap H);
    Tree Delete(Heap H);
    int WPL(Tree T, int depth);
    bool Judge();
    void JudgeTree(Tree T);
    
    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);
        //printf("%d
    ",codelen);
        
        cin >> m;
        while (m--)
        {
            if (Judge())
            {
                printf("Yes
    ");
            }
            else
            {
                printf("No
    ");
            }
        }
        
        return 0;
    }
    
    Tree creatTree()
    {
        Tree T = new TreeNode;
        T->left = T->right = NULL;
        T->weight = 0;
        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 (; H->Data[i/2].weight > T.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 parent,child;
        TreeNode Tmp = 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+1].weight < H->Data[child].weight)
            {
                child++;
            }
            
            if (H->Data[child].weight > Tmp.weight)
            {
                break;
            }
            H->Data[parent] = H->Data[child]; 
        }
        H->Data[parent] = Tmp;
        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;
        int wgh;
        
        for (int i = 0;  i < n; i++)
        {
            cin >> s1 >> s2;
            
            if (strlen(s2) > n)
            {
                return 0;
            }
            
            int j;
            for (j = 0; ch[j] != s1[0]; 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;
        }
        cnt0 = cnt2 = 0;
        JudgeTree(T);
        
        if (cnt2 != cnt0-1)
        {
            return 0;
        }
        if (codelen == WPL(T,0))
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    
    void JudgeTree(Tree T)
    {
        if (T)
        {
            if (!T->left && !T->right)
            {
                cnt0++;
            }
            else if(T->left && T->right)
            {
                cnt2++;
            }
            else
            {
                cnt0 = 0;
            }
            
            JudgeTree(T->left);
            JudgeTree(T->right);
        }
    }
     
  • 相关阅读:
    [转]微信开发者工具webview无法console.log
    poi maven依赖与 poi新旧版本样式设置更新问题 database
    [转]Uniapp的webview,H5页面在微信小程序中webview再跳回小程序的解决方案
    [Golang] goland开启自动格式化
    [前端] ElementUI 中table表格数据解析渲染html格式
    GOFLY在线客服系统_微信小程序客服对接_小程序webview内嵌访客链接教程
    [TCP] write: broken pipe 的 原因
    [微信开发] 解决:该公众号提供的服务出现故障,请稍后再试
    客服在线咨询工具|即时聊天客服系统下载安装(包含APP)
    网站客服系统_网页客服系统安装使用_GOFLY在线客服系统
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11783768.html
Copyright © 2020-2023  润新知