【PTA】05-树9 Huffman Codes(30 分) 优先队列

题目链接


思路:

1.记录频率

①用数组记录要编码的字符(char ch[N];)

②建立map容器Time,用Time[字符]记录字符的使用次数

2.建立Huffman树,计算出最少花费

①用优先队列建Huffman树

②计算最少花费(用队列层序遍历Huffman树)

3.比较测试数据

花费是否最少    ----如果不是---->输出no (编码长度*字符使用次数)

②是否没有歧义    (比较前缀,用map容器,从小到大标记,每次标记前判断子段是否已经被标记)


#include 

using namespace std;

const int N = 100;
int n;
char ch[N];
map Time;

struct node
{
    char c[N];
    int len;
}code[N];

typedef struct tree
{
    int sum;
    struct tree* left;
    struct tree* right;
    char c;
}*Tree;

struct cmp
{
    bool operator()(const Tree x, const Tree y)
    {
        return x->sum > y->sum;
    }
};

int BuildHuffman()
{
    int sum = 0;//记录花费
    priority_queue, cmp> que;

    for(int i = 1; i <= n; i++)
    {
        Tree treenode = (Tree)malloc(sizeof(struct tree));
        treenode->c = ch[i];
        treenode->left = NULL;
        treenode->right = NULL;
        treenode->sum = Time[ch[i]];
        que.push(treenode);
    }
    while(que.size() > 1)
    {
        Tree lchild = que.top();
        que.pop();
        Tree rchild = que.top();
        que.pop();
        Tree father = (Tree)malloc(sizeof(struct tree));
        father->left = lchild;
        father->right = rchild;
        father->sum = lchild->sum + rchild->sum;
        que.push(father);
    }

    Tree head = que.top();
    typedef pair P;
    queue

q; q.push(P(head,0)); while(!q.empty())//树的层序遍历 { P p = q.front(); q.pop(); if(p.first->left) q.push(P(p.first->left, p.second+1)); if(p.first->right) q.push(P(p.first->right, p.second+1)); if(!p.first->left && !p.first->right) sum += Time[p.first->c]*p.second; } return sum; } int cmp1(const struct node x, const struct node y) { return x.len < y.len; } bool Only() { map mp; sort(code+1,code+1+n,cmp1); string s; for(int i = 1; i <= n; i++) { s.clear(); for(int j = 0; j < code[i].len; j++) { s += code[i].c[j]; if(mp[s]) return 0; } mp[s] = 1; } return 1; } int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf(" %c", &ch[i]);//ch保存字符,便于遍历所有字符 scanf("%d", &Time[ch[i]]);//用MAP容器记录字符使用次数(方便调用) } int Minmum = BuildHuffman();//记录最优花费 int m; scanf("%d", &m); while(m--) { int flag = 0; char c; int SumCost = 0; for(int i = 1; i <= n; i++) { scanf(" %c %s", &c, code[i].c); code[i].len = strlen(code[i].c); SumCost += Time[c]*code[i].len;//算花费 } if(SumCost > Minmum) printf("No\n"); else if(!Only()) printf("No\n"); else printf("Yes\n"); } return 0; }



你可能感兴趣的:(WA)