zoukankan      html  css  js  c++  java
  • HDU_1053 Entropy

      这道题目的长度很吓人,其实就是一道很裸的Hufuman编码问题,一般的《数据结构》书上都有,不说了,上代码:

    #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;
    }
    elseif(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);
    }
    return0;
    }
  • 相关阅读:
    CentOS7中Tomcat的安装和配置
    CentOS7中JDK的安装和配置
    Linux基本指令
    MySQL数据库索引:索引介绍和使用原则
    MongoDB基础篇2:数据库/用户/数据集合的增删改
    MongoDB基础篇1:安装和服务配置
    JSTL fn:replace()函数替换 换行符
    LeetCode440. 字典序的第K小数字
    kubeadm搭建kubernetes-1.13.2集群
    kubernetes(k8s)kubectl使用详解
  • 原文地址:https://www.cnblogs.com/vongang/p/2130588.html
Copyright © 2011-2022 走看看