本题目要求针对给定的字符串,按照哈夫曼编码原理对其进行编码(即:转换为01串),并输出其对应的哈夫曼编码。注:字符串中的字符按照ASCII码给定序号,如vggba这个字符串中的字符序号分别为43321;构建哈夫曼树时则按照序号顺序排列字符,如权值最小的两个字符为a和b,而不是b和a。
输入格式:
输入一个整数n,然后依次输入n个字符串。
输出格式:
针对每个输入的字符串,输出其哈夫曼编码。
输入样例:
2 avvvdddeeeffffgggggjk eeeffrnvjshvhssnn
输出样例:
11110110110110100100100101101101000000000101010101111111110 11011011001001010111111001010000111000110000111111题解思路 前言
基本思路对于基本哈夫曼树的思想我就不做解释了,其实用来构造哈夫曼树的方法很多,例如小根堆(见往期博客),数组,结构等等,我之前尝试用小根堆解决本题,但是编码结果一直和本题结果不相同,一种原因是,在removefirst之后的小根堆重建时,可能会导致相同权重的叶节点无法按照题目要求的ASCII码排序,但本次用的 struct类型的数组则不会出现这种问题。
我们利用一个两倍长度数组来存储节点,前n个就是原本的叶子节点,后面n个就是我们不断合并的新节点,因为最开始我们是用 map 来存给定字符串的 value 和 weight,其中的顺序就是按照 value的ASCII 码的升序,同时我们是从前往后遍历,所以在构建 huffman 树的过程并不会破坏这种排序,结合代码和注释理解理解叭--------
#includeusing namespace std; const int MAX = 50; map codeMap; //存编码 struct huffNode { char val; int weight; int left; int right; int parent; string code; }; //初始化每个节点 void init(huffNode * huffTree, int *wgt, char *value, int n) { for (int i = 0; i < 2*n-1; i++) { huffTree[i].val = value[i]; huffTree[i].weight = wgt[i]; huffTree[i].left = -1; huffTree[i].right = -1; huffTree[i].parent = -1; } } //建立一颗huffTree //我们把空间定义为叶子节点的2倍,然后合并的节点就往后加 //找到权重最小的两个节点合并,然后放到后面 //因为我们是从前往后找,所以能保证是按照ASCII升序 void setHuffTree(huffNode * huffTree, int n) { int min1,min2,pos1,pos2; for (int i = n; i < 2*n-1; i++) { //新节点的位置 min1 = min2 = INT_MAX; pos1 = pos2 = 0; for (int j = 0; j < i; j++) { //找到当前范围内的权重唯二最小 if (huffTree[j].parent == -1 && huffTree[j].weight < min1) { min2 = min1; pos2 = pos1; min1 = huffTree[j].weight; pos1 = j; } else if (huffTree[j].parent == -1 && huffTree[j].weight < min2) { min2 = huffTree[j].weight; pos2 = j; } } //建立联系 huffTree[pos1].parent = i; huffTree[pos2].parent = i; huffTree[i].left = pos1; huffTree[i].right = pos2; huffTree[i].weight = min1+min2; } } void huffCode(huffNode *huffTree, int n) { for (int i = 0; i < n; i++) { string nodeCode = ""; int parent = huffTree[i].parent; int curr = i; while (parent != -1) { //一直找到根节点 if (huffTree[parent].left == curr) //左孩子 nodeCode += "0"; else nodeCode += "1"; curr = parent; parent = huffTree[parent].parent; } reverse(nodeCode.begin(),nodeCode.end()); huffTree[i].code = nodeCode; //存到map里,方便后面输出 codeMap[huffTree[i].val] = nodeCode; } } int main() { int N; cin >> N; while (N--) { map valMap; string str = ""; cin >> str; for(auto x : str) valMap[x]++; int n = valMap.size(); char *val = new char(MAX); int *wgt = new int(MAX); huffNode huffTree[MAX]; int i = 0; for(auto it=valMap.begin(); it!=valMap.end();it++,i++) { val[i] = it->first; wgt[i] = it->second; } init(huffTree,wgt,val,n); setHuffTree(huffTree,n); huffCode(huffTree,n); string ans = ""; for (auto x : str) { ans += codeMap[x]; } cout << ans< 学习愉快!!!



