PAT 05-树8 Huffman Codes

以现在的生产力,是做不到一天一篇博客了。这题给我难得不行了,花了两天时间在PAT上还有测试点1没过,先写上吧。记录几个做题中的难点:1、本来比较WPL那块我是想用一个函数实现的,无奈我对传字符串数组无可奈何;2、实在是水平还不够,做题基本上都是要各种参考,当然以课件(网易云课堂《数据结构》(陈越,何钦铭))中给的方法为主,可是呢,关于ElementType的类型我一直确定不下来,最后还是参考了园友糙哥(http://www.cnblogs.com/liangchao/p/4286598.html#3158189)的博客;3、关于如何判断是否为前缀码的方法,我是用的最暴力的一一对比,不知如何能更好的实现。好了,具体的题目及测试点1未过的代码实现如下

  1 /*
  2     Name: 
  3     Copyright: 
  4     Author: 
  5     Date: 07/04/15 11:05
  6     Description: 
  7 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.
  8 
  9 Input Specification:
 10 
 11 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:
 12 
 13 c[1] f[1] c[2] f[2] ... c[N] f[N]
 14 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:
 15 
 16 c[i] code[i]
 17 where c[i] is the i-th character and code[i] is a string of '0's and '1's.
 18 
 19 Output Specification:
 20 
 21 For each test case, print in each line either “Yes” if the student’s submission is correct, or “No” if not.
 22 
 23 Sample Input:
 24 7
 25 A 1 B 1 C 1 D 3 E 3 F 6 G 6
 26 4
 27 A 00000
 28 B 00001
 29 C 0001
 30 D 001
 31 E 01
 32 F 10
 33 G 11
 34 A 01010
 35 B 01011
 36 C 0100
 37 D 011
 38 E 10
 39 F 11
 40 G 00
 41 A 000
 42 B 001
 43 C 010
 44 D 011
 45 E 100
 46 F 101
 47 G 110
 48 A 00000
 49 B 00001
 50 C 0001
 51 D 001
 52 E 00
 53 F 10
 54 G 11
 55 Sample Output:
 56 Yes
 57 Yes
 58 No
 59 No
 60 */
 61 #include <stdio.h>
 62 #include <stdlib.h>
 63 #include <string.h>
 64 
 65 #define MinData 0
 66 
 67 typedef struct TreeNode
 68 {
 69     int Weight;
 70     struct TreeNode * Left, * Right;
 71 }HuffmanTree, * pHuffmanTree;
 72 typedef struct HeapStruct
 73 {
 74     pHuffmanTree Elements;
 75     int Size;
 76     int Capacity;
 77 }MinHeap, * pMinHeap;
 78 
 79 pMinHeap Create(int MaxSize);
 80 void Insert(pMinHeap pH, HuffmanTree item);
 81 pHuffmanTree Huffman(pMinHeap pH);
 82 pHuffmanTree DeleteMin(pMinHeap pH);
 83 int getWPL(pHuffmanTree pT, int layer, int WPL);
 84 
 85 int main()
 86 {
 87 //    freopen("in.txt", "r", stdin); // for test
 88     int N, i; // get input
 89     scanf("%d", &N);
 90     int a[N];
 91     char ch;
 92     for(i = 0; i < N; i++)
 93     {
 94         getchar();
 95         scanf("%c", &ch);
 96         scanf("%d",&a[i]);
 97     }
 98     
 99     int WPL = 0; // build min-heap and Huffman tree
100     pMinHeap pH;
101     HuffmanTree T;
102     pH = Create(N);
103     for(i = 0; i < N; i++)
104     {
105         T.Weight = a[i];
106         T.Left = NULL;
107         T.Right = NULL;
108         Insert(pH, T);    
109     }
110     pHuffmanTree pT;
111     pT = Huffman(pH);
112     
113     WPL = getWPL(pT, 0, WPL); // compare WPL
114     int M, j, k;
115     scanf("%d", &M);
116     int w[M], flag[M];
117     char s[N][N + 2];
118     for(i = 0; i < M; i++)
119     {
120         w[i] = 0;
121         flag[i] = 0;
122         for(j = 0; j < N; j++)
123         {
124             getchar();
125             scanf("%c", &ch);
126             scanf("%s", s[j]);
127             w[i] += strlen(s[j]) * a[j];
128         }
129         if(w[i] == WPL)
130         {
131             flag[i] = 1;
132             for(j = 0; j < N; j++)
133             {
134                 for(k = j + 1; k < N; k++)
135                 {
136                     if(strlen(s[j]) != strlen(s[k]))
137                     {
138                         if(strlen(s[j]) >strlen(s[k]))
139                             if(strstr(s[j], s[k]) == s[j])
140                             {
141                                 flag[i] = 0;
142                                 break;
143                             }
144                         else
145                             if(strstr(s[k], s[j]) == s[k])
146                             {
147                                 flag[i] = 0;
148                                 break;
149                             }
150                     }
151                 }
152             }
153         }
154     }
155     
156     for(i = 0; i < M; i++)
157     {
158         if(flag[i])
159             printf("Yes\n");
160         else
161             printf("No\n");
162     }
163 //    fclose(stdin); // for test
164     return 0;
165 }
166 
167 pMinHeap Create(int MaxSize)
168 {
169     pMinHeap pH = (pMinHeap)malloc(sizeof(MinHeap));
170     pH->Elements = (pHuffmanTree)malloc((MaxSize + 1) * sizeof(HuffmanTree));
171     pH->Size = 0;
172     pH->Capacity = MaxSize;
173     pH->Elements[0].Weight = MinData;
174     
175     return pH;
176 }
177 
178 void Insert(pMinHeap pH, HuffmanTree item)
179 {
180     int i;
181     
182     i = ++pH->Size;
183     for(; pH->Elements[i / 2].Weight > item.Weight; i /= 2)
184         pH->Elements[i] = pH->Elements[i / 2];
185     pH->Elements[i] = item;
186 }
187 
188 pHuffmanTree Huffman(pMinHeap pH)
189 {
190     int i;
191     pHuffmanTree pT;
192     
193     for(i = 1; i < pH->Capacity; i++)
194     {
195         pT = (pHuffmanTree)malloc(sizeof(HuffmanTree));
196         pT->Left = DeleteMin(pH);
197         pT->Right = DeleteMin(pH);
198         pT->Weight = pT->Left->Weight + pT->Right->Weight;
199         Insert(pH, *pT);
200     }
201     pT = DeleteMin(pH);
202     
203     return pT;
204 }
205 
206 pHuffmanTree DeleteMin(pMinHeap pH)
207 {
208     int Parent, Child;
209     pHuffmanTree pMinItem;
210     HuffmanTree temp;
211     
212     pMinItem = (pHuffmanTree)malloc(sizeof(HuffmanTree));
213     *pMinItem = pH->Elements[1];
214     temp = pH->Elements[pH->Size--];
215     for(Parent = 1; Parent * 2 <= pH->Size; Parent = Child)
216     {
217         Child = Parent * 2;
218         if((Child != pH->Size) && (pH->Elements[Child].Weight > pH->Elements[Child + 1].Weight))
219             Child++;
220         if(temp.Weight <= pH->Elements[Child].Weight)
221             break;
222         else
223             pH->Elements[Parent] = pH->Elements[Child];
224     }
225     pH->Elements[Parent] = temp;
226     
227     return pMinItem;
228 }
229 
230 int getWPL(pHuffmanTree pT, int layer, int WPL)
231 {
232     if(pT->Left == NULL && pT->Right == NULL)
233         WPL += layer * pT->Weight;
234     else
235     {
236         WPL = getWPL(pT->Left, layer + 1, WPL);
237         WPL = getWPL(pT->Right, layer + 1, WPL);
238     }
239     
240     return WPL;
241 }

 

转载于:https://www.cnblogs.com/qingkai/p/4403504.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Huffman编码是一种用于数据压缩的算法,它通过将出现频率较高的字符用较短的编码表示,从而减少数据的存储空间。该算法的基本思想是构建一棵哈夫曼,将字符的出现频率作为权值,然后从叶子节点开始向上遍历,将左子标记为,右子标记为1,最终得到每个字符的编码。哈夫曼编码具有唯一性,即每个字符都有唯一的编码,且任何一个编码都不是另一个编码的前缀。 ### 回答2: Huffman编码是一种压缩数据的方式。它使用的基本原理是将数据中频繁出现的字符使用较短的编码,而不常用的字符使用较长的编码,以达到压缩数据的目的。在Huffman编码中,我们使用二叉来表示每个字符的编码。左孩子被标记为0,右孩子被标记为1。当我们从根节点到叶子节点的路径上移动时,我们收集的所有0和1的序列将编码作为该字符的压缩表示。 具体来说,生成Huffman编码的过程包括以下步骤: 1. 统计给定数据集中每个字符出现的次数。 2. 将字符作为叶子节点构建二叉,每个叶子节点包含一个字符和该字符的频率。 3. 选择频率最小的两个节点,将它们作为左右子合并成一个新节点,其频率等于两个节点频率之和。 4. 将新节点插入二叉,并在每个节点添加一个标记为0或1的位。 5. 重复步骤3和步骤4,直到只剩下一个节点。 6. 通过遍历收集每个字符的Huffman编码。递归,并在每个节点处添加0或1,直到我们到达一个叶子节点。 Huffman编码的优点在于它可以使数据更紧凑,占用更少的存储空间。它也是在许多压缩和编码算法中广泛应用的基础。Huffman编码的缺点是在压缩小数据时,压缩效果可能不明显。这是因为压缩率受到输入数据的分布和大小的影响。在Huffman编码中,来自数据集的所有字符的比特序列可能具有不同的长度。因此,我们需要在压缩和解压缩时花费一些额外的时间来恢复原始数据。 总之,Huffman编码是一种有效的数据压缩算法,可以通过使用二叉来表示每个字符的编码来实现。它的主要优点是可以更紧凑地存储数据,但它仍然受到输入数据大小和分布的影响,并且在进行压缩和解压缩时需要花费额外的时间。 ### 回答3: 题目描述 Huffman code是一种贪心算法,用于编码数据,每个字符都对应一种可辨识的前缀二进制码,使得所有字符的编码总长度最短。给定n个权值作为n个叶子结点,构造一棵二叉,若该的带权路径长度达到最小,则称这样的二叉为最优二叉,也称为赫夫曼。 在赫夫曼中,每个叶子节点的权值就是原始数据中的权值,而非叶子节点不存储权值,比较特别的一种二叉。 输入格式 第1行: 一个正整数n(<=1000) 接下来n行: 每行一个正整数weight[i](weight[i]<=100000) 输出格式 共n-1行,为赫夫曼编码表,每个字符的赫夫曼编码占据一行。 样例输入1 5 1 3 2 10 5 样例输出1 0 110 111 10 11 样例输入2 5 23 3 6 16 8 样例输出2 100 0 101 1101 1100 解题思路 首先,将所有节点的权值从小到大排序。 接着构造一棵二叉: 每次从节点集合中选出最小的两个节点(即最小的两个权值) 将这两个点组成一棵新的二叉,其权值为这两个节点权值之和,这棵新的左右子即为这两个节点。 把这棵新加入到权值序列中,其位置按照新的权值插入,继续循环,直到权值序列只含有一个节点为止,这个节点就是赫夫曼的根。 最后,根据赫夫曼将每个叶子节点的编码求出来,一般情况下,将左子编码置“0”,右子编码置“1”,然后做前缀无歧义编码,按照这种编码方式,我们得到了每个节点的Huffman编码。 代码实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值