日常,这一次,耗费我三天,其实第二天时便已经将 对整个框架有清晰的了解了,(看了解析了),但是一步步排除,确实让我学到了很多。
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', '_'}, andf[i]
is the frequency ofc[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 thei
-th character andcode[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
面对这样的代码, 务必清晰
typedef struct TNode *HF; typedef struct Heap *MinHeap; struct TNode{ int weight; HF Left; HF Right; }; struct Heap{ HF *data; int size; int capacity; }; MinHeap Init_Heap(int num) { MinHeap H; H = (MinHeap)malloc(sizeof(struct Heap)); H ->data = (HF*)malloc(sizeof(struct TNode) * (num + 1)); H->data[0] = (HF)malloc(sizeof(struct TNode)); H ->data[0] ->weight = -1; H ->data[0] ->Left = NULL; H ->data[0] ->Right = NULL; H ->size = 0; return H; }
我,最开始对
H->data[0]=(Huffman)malloc(sizeof(struct TreeNode));
也不解,甚至写出了,
void attach(HF H, HF T) { HF ->weight = T ->weight; HF ->Left = T ->Left; HF ->Right = T ->Right; free(T); } //这样的代码
后来明白了HF *data,可以视为 struct TNode **data;
H-> data 指分配了(num+1)大小的指针数组,
H ->data[0]指分配一个struct TNode空间,理解 struct TNode *data[0];(这里data[0])
哈哈,C语言就是这样,指针我也只是粗略的了解,加油
我的AC代码:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<stdbool.h>
#include<string.h>
typedef struct TNode *HF;
typedef struct Heap *MinHeap;
struct TNode{
int weight;
HF Left;
HF Right;
};
struct Heap{
HF *data;
int size;
int capacity;
};
MinHeap Init_Heap(int num);
HF Init_Huffman();
void Insert_Heap(MinHeap H, HF T);
HF Pop_Node(MinHeap H);
HF Build_Huffman();
HF Build_Huffman(int num, int *code, char *ch);
int WPL(HF T, int depth);
bool Judge_Huffman(int num, int wpl, int *code, char *ch);
int main()
{
int num;
HF T;
MinHeap H;
char *ch;
int *code, wpl;
int test;
scanf("%d", &num);
ch = (char*)malloc(sizeof(char) * (num + 1));
code = (int*)malloc(sizeof(int) * (num + 1));
T = Build_Huffman(num, code, ch);
wpl = WPL(T, 0);
scanf("%d", &test);
while(test--){
if(Judge_Huffman(num, wpl, code, ch)){
printf("Yes\n");
}else{
printf("No\n");
}
}
return 0;
}
HF Build_Huffman(int num, int *code, char *ch)
{
MinHeap H;
HF T;
int i, n;
H = Init_Heap(num);
for(i = 1; i <= num; i++){
scanf(" %c %d", &ch[i], &code[i]);
if(isalpha(ch[i]) && isupper(ch[i]) && code[i] > 0);
else{
printf("错误!请检查输入字符。\n");
}
T = Init_Huffman();
T ->weight = code[i];
Insert_Heap(H, T);
}
n = H->size;
for(int i=1; i < n; i++)
{
T= Init_Huffman();
T->Left = Pop_Node(H);
T->Right = Pop_Node(H);
T->weight = T->Left->weight+T->Right->weight;
Insert_Heap(H,T);
}
T = Pop_Node(H);
return T;
}
int WPL(HF T, int depth)
{
if(!(T ->Left) && !(T ->Right)){
return (T ->weight * depth);
}else{
return WPL(T ->Left, depth + 1) + WPL(T ->Right, depth + 1);
}
}
MinHeap Init_Heap(int num)
{
MinHeap H;
H = (MinHeap)malloc(sizeof(struct Heap));
H ->data = (HF*)malloc(sizeof(struct TNode) * (num + 1));
H->data[0] = (HF)malloc(sizeof(struct TNode));
H ->data[0] ->weight = -1;
H ->data[0] ->Left = NULL;
H ->data[0] ->Right = NULL;
H ->size = 0;
return H;
}
HF Init_Huffman()
{
HF T;
T = (HF)malloc(sizeof(struct TNode));
T ->weight = 0;
T ->Left = NULL;
T ->Right = NULL;
return T;
}
void Insert_Heap(MinHeap H, HF T)
{
int i;
i = ++(H->size);
for(; T ->weight < H ->data[i/2]->weight; i /=2){
H ->data[i] = H ->data[i/2];
}
H ->data[i] = T;
}
HF Pop_Node(MinHeap H)
{
HF Temp, Min;
int Child, Parent;
Min = H ->data[1];
Temp = H ->data[(H ->size)--];
for(Parent = 1; Parent * 2 <= H ->size; Parent = Child){
Child = Parent * 2;
if((Child != H ->size) && (H->data[Child]->weight > H->data[Child+1]->weight)){
Child++;
}
if(Temp ->weight <= H ->data[Child] ->weight) break;
else{
H ->data[Parent] = H ->data[Child];
}
}
H ->data[Parent] = Temp;
return Min;
}
bool Judge_Huffman(int num, int wpl, int *code, char *ch)
{
HF T, Temp;
char c, *codes;
int j, wgh;
int length = 0;
bool flag = true;
T = Init_Huffman();
codes = (char*)malloc(sizeof(char) * (num - 1));
if(!codes) printf("没有分配成功\n");
while(num --){
scanf(" %c %s", &c, codes);
for(j = 1; c != ch[j]; j++);
wgh = code[j];
Temp = T;
for( j = 0; j < strlen(codes); j++){
if(codes[j]=='0'){
if(!Temp->Left)
Temp->Left = Init_Huffman();
Temp = Temp->Left;
}else if(codes[j] == '1'){
if(!Temp->Right)
Temp->Right = Init_Huffman();
Temp = Temp->Right;
}if(Temp->weight){
flag = false;
}
}
if(Temp->Left || Temp->Right)
flag = false;
else{
Temp->weight = wgh;
}
length += strlen(codes) * Temp->weight;
}
free(codes);
if(length != wpl)
flag = false;
return flag;
}