[时间]:6h+

[难度]:中等偏难 (主要是3条性质初学者难以发现)

[reference]: 

  • 《数据结构》05-树9 Huffman Codes_叫我皮卡丘的博客-CSDN博客

[反思,收获]:    

学习方法: 关键是在理论上拿下这个题;(能否发现那3条性质)        先在草稿纸上写出框架(伪码),然后再具体上级coding,不选择好策略就上战场是一种愚蠢的表现---提前分析框架的重要性;        某些性质能够在数据结构的形成过程中能够计算出来(WPL),这样我就可以避免不建huffman树;        自己和自己说话,不然自己大脑容易陷入”乌云“当中;自己很辣鸡,多学习多学习多学习啊!        ASCII码一般是128位(8bits里第一位一般为0,只剩7位可供使用,2的7次方=128),所以直接建立一个元素个数位128的数组字节存储它们的元素值和频率---直接映射以加快寻找速度;        在状态过程中游离,看看能否发现它们之间存在的规律。

[hints]: 可以不创建树的物理结构

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 (≤1000), 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

-------------------------------------------------------     line    -------------------------------------------------------------

Goal:

  • I.计算mini_WPL;
  • II.判断是否符合前缀码;

I.计算mini_WPL

v1.基本去模拟(代码量大),先建立huffmanTree实体结构,再通过HuffmanTree计算WPL.这里容易误导我们以为必须建立HuffTree才能计算WPL,实则不然.

v2.小根堆模拟huffman建立过程,只是并不产生实体,若把小根堆的元素换成huffman节点,那就是在建立huffmanTree.

II.判断是否符合前缀码

v1.建树去模拟

v2.直接比较内容,任意取两个字符串(s1, s2)去与(|)得到结果result(=s1 & s2), 若result 和s1,s2其中之一相等就肯定出现重复.        drawback:时间复杂度太高, O(n^2)

/**index   ch  fre0       A   21       B   2...*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>struct tablenode{char ch;int frequency;
}Table[128];
// remember to clear the spacestruct HeapNode{int *Ele;int size;int capacity;
};
typedef struct HeapNode* Heap;typedef struct huffnode{int Isleaf;struct huffnode* lc;struct huffnode* rc;
}*HuffNode;void myread(Heap h, int n);
Heap CreateSmallHeap(int maxsize);
void Insert2Heap(Heap smallheap, int X);
void Initialize(Heap smallheap);
int DeleteOfHeap(Heap smallheap);
void AdjustSubheap(Heap smallheap, int index);
int WPL(Heap smallheap);
int JudgeHuff(int dst_wpl, int n);
HuffNode NewHuff();
void FreeHuff(HuffNode root);
int main(){int i, n, dst_wpl, group;memset(Table, 0, 128*sizeof(struct tablenode));Heap h = CreateSmallHeap(64);scanf(" %d", &n);myread(h, n);dst_wpl = WPL(h);scanf(" %d", &group);for(i=0; i<group; i++){JudgeHuff(dst_wpl, n);}return 0;
}/***  判断一次Huffmancode是否符合要求. 两个角度:1.长度,2.前缀*  注意:一定要有n次输入,不能失败就结束程序*/
int JudgeHuff(int dst_wpl, int n){int i, j, tag=1, wpl=0;char buff[65], c;HuffNode root = NewHuff(), p=root;for(i=0; i<n; i++){p=root;                     // need to be initialized every timescanf(" %c %s", &c, buff);int len = strlen(buff);if( tag && len > n-1){tag = 0;}if( tag ){  //计算wpl和判断是否符合前缀码wpl += len* Table[ (int) c].frequency;j=0;while( tag && j < len){if( p->Isleaf){ //control go to a leaf but buffcoding still have more characterstag=0;break;}switch(buff[j]){case '0':if( !p->lc ){p->lc = NewHuff();p = p->lc;if(j == len-1){p->Isleaf = 1;}}else{  // node is existedif( (j<len-1 && p->lc->Isleaf) || j==len-1 ){tag=0;break;}p = p->lc;}break;case '1':if( !p->rc ){p->rc = NewHuff();p = p->rc;if(j == len-1){p->Isleaf = 1;}}else{  // node is existedif( (j<len-1 && p->rc->Isleaf) || j==len-1 ){tag=0;break;}p = p->rc;}break;default:printf("Buff[] Error!\n");exit(1);}j++;}}}FreeHuff(root);if(tag == 1 && wpl == dst_wpl){printf("Yes\n");}else{printf("No\n");}return 0;
}/****/
void FreeHuff(HuffNode root){if(root == NULL){return ;}if(root->lc){FreeHuff(root->lc);}if(root->rc){FreeHuff(root->rc);}free(root);
}/***  creat a huffnode*/
HuffNode NewHuff(){HuffNode p  = malloc(sizeof(struct huffnode));if(!p){printf("Out of memory!\n");exit(1);}p->Isleaf = 0;p->lc = NULL;p->rc = NULL;return p;
}void myread(Heap h, int n){int i, buff;char c;for(i=0; i<n; i++){scanf(" %c",&c);scanf(" %d", &buff);//insert data in to heaph->Ele[i+1] = buff;h->size++;Table[ (int)c].frequency = buff;}Initialize(h);return;
}/***  按照给定的大小建立一个小根堆,小根堆中下标0元素放置了最小元素--哨兵*/
Heap CreateSmallHeap(int maxsize){int *arr = (int *)malloc( (maxsize+1) * sizeof(int));Heap h = (Heap) malloc(sizeof(struct HeapNode));h->Ele = arr;h->size = 0;h->capacity = maxsize;arr[0] =  1<<((sizeof(int)*8)-1) ; //minimum in intreturn h;
}void Insert2Heap(Heap smallheap, int X){int i, p;Heap h = smallheap;++(h->size);//从上往下拉,让出合适的位置给新插入的元素Xfor( i=h->size; X < h->Ele[i/2]; i=p){p = i/2;if( X < h->Ele[p]){h->Ele[i] = h->Ele[p];continue;}break;}h->Ele[i] = X;
}/***  return: the value of the element that be deleted*/int DeleteOfHeap(Heap smallheap){if(smallheap->size <=0 ){printf("DeleteOfheap() Error! heap is empty\n");exit(1);}int ret_val = smallheap->Ele[1];int new_val = smallheap->Ele[smallheap->size--];// new_value replace the root then adjusting the subheapsmallheap->Ele[1] = new_val;AdjustSubheap(smallheap, 1);return ret_val;}/*** adujust the subheap whose index is index from top-down* premise: the root of the subheap is modified*/
void AdjustSubheap(Heap smallheap, int index){int size = smallheap->size;if(index > size/2 || index < 1){    // return if the node is leavesreturn ;}int i, child_pos;int new_val = smallheap->Ele[index];for(i=index; i*2<=size; i = child_pos){         // adjust from top to downchild_pos=2*i;//if right child is existedif(child_pos+1 <= size){if(smallheap->Ele[child_pos] > smallheap->Ele[child_pos+1]){child_pos++;}}if(smallheap->Ele[child_pos] < new_val){smallheap->Ele[i] = smallheap->Ele[child_pos];}else{break;}}smallheap->Ele[i] = new_val;return ;}/***    adjust elements in chaos to keep the propertied of heap*/
void Initialize(Heap smallheap){int size = smallheap->size;if(size < 2){return;}int i;for(i=size/2; i>0; i--){AdjustSubheap(smallheap, i);}
}/***  caculate WPL of a small Heap*/int WPL(Heap smallheap){int size = smallheap->size, rlt=0;int i;for(i=1; i<=size-1; i++){int tmp = DeleteOfHeap(smallheap);tmp += DeleteOfHeap(smallheap);rlt +=tmp;Insert2Heap(smallheap,tmp);}return rlt;}

05-tree9-huffmanCode相关推荐

  1. Go 中 time.Parse 报错:year/month/day hour/minute/second out of range 时间格式化为什么是 2006-01-02 15:04:05?

    1. 问题现象 在使用 Go 语言的 time.Parse 解析时间时遇到以下错误: func main() {timeParse, err := time.Parse("2006-11-0 ...

  2. [Buzz.Today]2011.05.25

    >> VMWare的Open Source Pass - CloudFoundry VMWare推出了开源Pass:CloudFoundary,但是现在只是支持少数几种语言与环境:Java ...

  3. 互动网计算机频道图书7日销售排行(05.20-05.26)

    互动网计算机频道图书7日销售排行(05.20-05.26) 1.Hadoop权威指南(中文版) 2.人人都是产品经理 3.演讲之禅:一位技术演讲家的自白 内容简介 本书既实用又引人入胜.作为职业演讲家 ...

  4. 函数05 - 零基础入门学习C语言36

    第七章:函数05 让编程改变世界 Change the world by program 函数的嵌套调用 嵌套定义就是在定义一个函数时,其函数体内又包含另一个函数的完整定义. 然而,C语言不能嵌套定义 ...

  5. 数据结构与算法:05 Leetcode同步练习(一)

    Leetcode同步练习(一) 题目01:两数之和 题号:1 难度:简单 https://leetcode-cn.com/problems/two-sum/ 给定一个整数数组 nums 和一个目标值 ...

  6. 05后都上清华了!首批丘成桐数学领军人才名单发布,三位菲尔兹奖得主为其授课,周末就来学校报到...

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 金磊 杨净 发自 凹非寺 量子位 报道 | 公众号 QbitAI 不 ...

  7. 指针05 - 零基础入门学习C语言45

    第八章:指针05 让编程改变世界 Change the world by program 字符串与指针 (1) 用字符数组存放一个字符串,然后输出该字符串. 例题一:定义一个字符数组,对它初始化,然后 ...

  8. 前端性能优化——从 10 多秒到 1.05 秒

    https://lishaoy.net 关于 性能优化 是个大的面,这篇文章主要涉及到 前端 的几个点,如 前端性能优化 的流程.常见技术手段.工具等. 提及 前端性能优化 ,大家应该都会想到 雅虎军 ...

  9. Galaxy Release (v 21.05),众多核心技术栈变更

    2021年6月初,Galaxy Project 正式发布了 release 21.05 版本:随后6月中旬,发布该版本的 announcement 文档.这里总结一下该版本一些主要的更新内容,为关注和 ...

  10. Galaxy Release 20.05 发布,新增多项可视化体验

    Galaxy Project(https://galaxyproject.org/)是在云计算背景下诞生的一个生物信息学可视化分析开源项目. 该项目由美国国家科学基金会(NSF).美国国家人类基因组研 ...

最新文章

  1. Node.js 简单入门
  2. 《Adobe Fireworks CS6中文版经典教程》——1.5使用多个文档
  3. Hdoj 1846.Brave Game 题解
  4. 应用调试(四)系统调用SWI
  5. 移动设备wap手机网页html5通过特殊链接:打电话,发短信,发邮件详细教程
  6. 初级PHP开发作品容易出现的几个不足
  7. 为什么会存在TIME_WAIT socket-详细分析No buffer space available
  8. python预测股票价格_python用线性回归预测股票价格
  9. oracle大数据量迁移,分批量导入样例(fetch...bulk collect)以及forall结合使用
  10. 使用SQL语句创建数据库
  11. 3月6日服务器例行维护公告,热血江湖官方网站·系统公告
  12. 论如何成为技术大牛,GitHub中国区前20名详解
  13. 3-3 uniapp、HTML5+、Native.js 功能代码汇总
  14. 最强 Python 数据可视化库,没有之一!
  15. 【Android】安卓webview播放视频白屏解决方法
  16. ref使用之react / react hook
  17. 一体的综合化云控平台
  18. hexo博客加入51LA网站流量统计
  19. 校园跳蚤市场平台/校园二手交易平台管理系统
  20. AVClass和AVOption

热门文章

  1. 做一个网站需要多少钱?有哪些费用组成?
  2. Docker——Docker的基础和安装
  3. 【全方面预防U盘病毒侵入】
  4. 使用CSDN—MarkDown编辑数学公式
  5. vue3 数学公式使用
  6. 从英文版VC到word复制粘贴的乱码问题
  7. 1048--黑箱子-2023/1/3
  8. 结构光三维重建1——四步相移原理
  9. 电脑版CSDN如何查看[我的收藏]/[我的关注]
  10. 杭州为什么让人羡慕?