我一直在尝试实现基于数字的霍夫曼编码算法。我已经完成了构建霍夫曼树的部分。但递归算法并没有按预期工作。它应该将树中的路径从根返回到指定节点,但它总是返回错误的路径。
奇怪的是,代码似乎正在做正确的事情,它可以找到真正的路径。但它返回的结果总是别的。
def get_encoding_for(symbol_p, node, encoding):
global encoded_string
result = encoding
if not isinstance(node, list):
if symbol_p == node:
encoded_string = result
return result
else:
for n in node:
index = str(node.index(n))
# print("Node {} with index {}".format(n, index))
result = get_encoding_for(symbol_p, n, encoding + index)
return result
使用简单的列表构建树。
The huffman tree looks like: [[3.0, [1.0, 2.0]], [4.0, 5.0]]
这是使用元素1,2,3,4,5的简单树的示例输出。
Loop 1.0. Node 1.0 -> Coding 010:
Loop 2.0. Node 2.0 -> Coding 011:
Loop 3.0. Node 3.0 -> Coding 00:
Loop 4.0. Node 4.0 -> Coding 10:
Loop 5.0. Node 5.0 -> Coding 11:
这就是我希望函数返回的内容,但它只返回我" 11"在所有五次迭代中。我不得不使用全局变量来拦截"正确的编码,我对此不满意......我认为问题在于回归。我已经尝试了很多回归的方法,但没有一种方法能够奏效。
有人能告诉我递归的错误吗?非常感谢你!
答案 0 :(得分:0)
在树中搜索一个项目有点棘手。递归完成后,返回需要指示成功(再次返回)或失败(再次递归)。迭代完成,返回很容易,但需要显式堆栈的可能搜索位置。以下是前者,利用了树的二进制结构。注1:我使用的名称使 me 更容易正确地编写。他们不一定“更好”。注2:我在测试中添加了“未找到”的案例。
def encoding(char, bintree, path):
if isinstance(bintree, list):
p = encoding(char, bintree[0], path+'0')
if p:
return p
return encoding(char, bintree[1], path+'1')
else:
return path if char == bintree else ''
# Test
hufftree = [[3, [1, 2]], [4, 5]]
for i in range(6):
print(encoding(i, hufftree, ''))
# Prints
010
011
00
10
11
答案 1 :(得分:0)
另一种方法(与我的第一个答案中的方法不同)是将生成路径与停止逻辑分开。
def paths(bintree):
if isinstance(bintree, list):
for i, p in ((0,'0'), (1,'1')):
for val, path in paths(bintree[i]):
yield (val, p + path)
else:
yield (bintree, '')
def encoding2(i, bintree):
for val, path in paths(hufftree):
if i == val:
return path
return ''
# Test
hufftree = [[3, [1, 2]], [4, 5]]
for v in paths(hufftree): print(v)
for i in range(6):
print(encoding2(i, hufftree))
# Prints
010
011
00
10
11
此时,人们可能会考虑创建一个dict映射值来编码。
huffdict = dict(paths(hufftree))
for i in range(6):
print(huffdict.get(i, ''))
# Prints same as above