• hdu 1053霍夫曼编码


    此题的思路和代码都是别人的,我觉得写得比较清晰,就直接复制过来吧。

    代码如下:

    #include <stdio.h>
    #include <string.h>
    #define N 128
    #define inf 0x7fffffff
    struct node
    {
        int val;    //权值
    int left, right, parent;
    }p[1000];
    int f[N];    //存放每个字母权值
    int len[N];     //统计编码的长度
    
    void hufuman(int n)
    {
        int i, min1, min2, pos1, pos2, flag;
        for(i =0; i < n; i++)
        {
            p[i].val = f[i];
            p[i].parent =-1;
            p[i].left =-1;
            p[i].right =-1;
        }
        while(1)    //构建Hufuman树
        {
            int mark1 =0, mark2 =0;
            min1 = min2 = inf;
            for(i =0; i < n; i++)        //每次取最小和第二小的元素
            {
                if(p[i].parent ==-1&& p[i].val < min1)
                {
                    if(min1 != min2)
                    {
                        min2 = min1;
                        pos2 = pos1;
                        mark2 =1;
                    }
                    min1 = p[i].val;
                    pos1 = i;
                    mark1 =1;
                }
                else if(p[i].parent ==-1&& p[i].val < min2)
                {
                    min2 = p[i].val;
                    pos2 = i;
                    mark2 =1;
                }
            }
            if(mark1 ==0|| mark2 ==0)    //如果没有则跳出,表示已经建好Hufuman树
    break;
            p[n].val = min1 + min2;
            p[pos1].parent = n;
            p[pos2].parent = n;
            p[n].left = pos1;
            p[n].right = pos2;
            p[n].parent =-1;
            n++;
        }
        for(i =0; i < n; i++)
        {
            if(p[i].right !=-1|| p[i].left !=-1)        //如果不是原有的元素,而是后来构建出来的,则说明编码长度已经统计完
    break;
            flag = i;
            len[i] =1;
            while(p[flag].parent !=-1)
            {
                len[i]++;    //统计编码长度(这地方没有必要得出Hufuman编码,这道题用不到)
                flag = p[flag].parent;    //跳到i的父节点,继续查找
            }
        }
        return;
    }
    int main()
    {
        char str[N];
        int data[N], i;
        while(gets(str) != NULL)
        {
            if(!strcmp(str, "END"))    break;
    
            memset(data, 0, sizeof(data));
            memset(f, 0, sizeof(f));
    
            for(i =0; i < strlen(str); i++)
                data[(int)str[i]]++;    //求出每个字母的权值
    
            int num =0;
            for(i =0; i <128; i++)
            {
                if(data[i] !=0)
                {
                    f[num++] = data[i];    //给每个字母编号num,并将权值存到f[]
                }
            }
            if(num ==1)
            {
                printf("%d %d 8.0\n",strlen(str)*8, f[0]);
                continue;
            }
            hufuman(num);
            int sum =0;
            for(i =0; i < num; i++)
            {
                if(len[i] !=1)
                    sum += (len[i]-1)*f[i];        //编码总长度 = sum(每个字母所对应的编码长度 * 字母出现的次数)
            }
            printf("%d %d %.1f\n", strlen(str)*8,sum, strlen(str)*8/(float)sum);
        }
        return 0;
    }
  • 相关阅读:
    【剧透高亮】最最最完整剧透加剧情详细解析
    iOS十六进制和字符串的相互转换
    Swift函数编程之Map、Filter、Reduce
    Swift中的Masonry第三方库——SnapKit
    swift中第三方网络请求库Alamofire的安装与使用
    针对苹果最新审核要求为应用兼容IPv6
    使用 Fastlane 实现 IOS 持续集成
    Fastlane为iOS带来持续部署
    @OBJC 和 DYNAMIC
    swift基本用法-数组array
  • 原文地址:https://www.cnblogs.com/chaosheng/p/2520381.html
Copyright © 2020-2023  润新知