问题描述
我正在尝试编写霍夫曼字符串编码算法。
我的解决方案是这样的:
- 由于字符串中的每个字母都有一个与之关联的特殊二进制代码,请搜索二进制树,并在找到一个字母后,使用二进制代码将其添加到映射中。 (我做错的地方是这里)
- 对字符串进行迭代,并为每个字母关联与地图字母的键关联的值。
我的树上没有印有树,即使坚硬也可以帮助您,但是这是我从字符串 abracadabra 中得到的,以及应该得到的东西:
正确的代码:000010000110110101111101011000111110110100111011101100101101110000110000110111100101111101010010
我得到的是:
00001000111011010110101111010101100011101011010
这是我的代码:
#include <algorithm>
#include <map>
string codes = "";
void getMapCharBinaryCode(Node root,string &prefix,map <char,string> &m){
if(!root) return;
if(root->value){
if(!m.count(root->value)){
m[root->value] = prefix;
prefix = "";
}
}
if(root->leftChild){
getMapCharBinaryCode(root->leftChild,prefix += "0",m);
}
if(root->rightChild){
getMapCharBinaryCode(root->rightChild,prefix += "1",m);
}
}
string encode(string text,Node tree){
// text is "abracadabra"
// create map for each char -> binary code
map<char,string> m;
string prefix = "";
getMapCharBinaryCode(tree,prefix,m);
// iterate on text and assign each letter with binary code from map
for(int i = 0; i < text.size(); i++) {
codes += m[text[i]];
}
return codes;
}
解决方法
使用prefix
保存叶子时,您正在销毁prefix = ""
中的代码,在该叶子上放回树并转到下一个分支时需要使用该代码。
您可以为prefix
维护一个存储区,并通过引用传递它。但是,您需要在上树和下树时管理prefix
的长度,并且无需添加0
,然后将1
添加到 that 表示两个分支,为右侧的分支添加01
而不是1
。
作为起点,您应该只按值传递prefix
,该值可以创建副本,但在管理上无需特别注意。摆脱&
并将prefix +=
替换为prefix +
。摆脱prefix = ""
,然后什么也不做。