霍夫曼编码单个字符而不使用查找表
Posted
技术标签:
【中文标题】霍夫曼编码单个字符而不使用查找表【英文标题】:Huffman encode single character without lookup table 【发布时间】:2019-02-09 02:52:02 【问题描述】:我正在尝试实现 Huffman 编码,但不知道如何在不生成查找表的情况下使用 trie 对字符进行编码。我不想做的是生成每个字符到其编码位串的映射。我正在尝试编写一种方法,该方法采用 Huffman trie 的根和一个字符并吐出正确的代码。
我编写了以下无法正常工作的代码。问题是,我不知道如何在得到正确的结果后让它停止。到达正确的叶节点后继续添加代码。
string lookup(HuffNode* root, char c, string prevCode, string direction)
string currentCode = prevCode + direction;
if(!root->isLeaf())
currentCode = lookup(root->getLeft(), c, currentCode, "0");
currentCode = lookup(root->getRight(), c, currentCode, "1");
else
if(root->getChar() == c)
return currentCode;
else
return prevCode;
return currentCode;
string encodeChar(HuffNode* trie, char c)
return lookup(trie, c, "", "");
从 trie 中获取字符编码的正确方法是什么?
【问题讨论】:
如何确定您何时到达了正确的叶子,为什么您的程序不这样做? @ScottHunter 正确的叶子将是其数据成员与首先作为参数传递给encodeChar
方法的字符相同的叶子。问题不在于程序不知道何时到达正确的叶子节点,而是在程序确定找到正确的节点后,堆栈上仍有递归调用。
【参考方案1】:
每次要发出代码时都必须搜索树的一大块,这将是非常低效的。实际上,您应该为每个符号制作一个代码表。
在任何情况下,您需要做的是在一个通过引用传递的单个字符串中构建代码。不要返回字符串。 (当它在最初通过引用传递的字符串中完成时,它将在那里。)如果在叶子中找到符号,则返回 true 或 false。然后当你在每个分支上调用lookup()
时,看看它是否返回true。如果是,则立即返回 true。对于每个调用,将适当的位添加到字符串(0 或 1)。如果它为第二个分支返回 false,则删除您添加的位,并返回 false。
然后如果找到符号,原始调用将返回true,并且字符串将具有代码。如果返回 false,则符号不在任何叶子中,字符串将为空。
【讨论】:
哦,当然。读到这里,我为自己没有想到这一点而自责。感谢第二双眼睛。以上是关于霍夫曼编码单个字符而不使用查找表的主要内容,如果未能解决你的问题,请参考以下文章