如何解决用递归进行霍夫曼解码
我正在创建一个可以编码和解码文本的霍夫曼类,但我的解码方法有问题。我的编码方法工作正常,我的解码方法适用于少量文本。但是当我尝试解码大量文本时,我得到了最大递归深度错误并且不知道如何修复它。该类接收包含字符及其频率的字典,然后将它们转换为节点并构建树。构建树后,它将字符及其位码放入另一个字典中,用于编码和解码。
class Node:
def __init__(self,value,data,left=None,right=None):
#Holds frequency
self.value = value
#Holds character
self.data = data
self.left = left
self.right = right
self.code = ""
def __lt__(self,other):
return self.value < other.value
def __le__(self,other):
return self.value <= other.value
def __gt__(self,other):
return self.value > other.value
def __ge__(self,other):
return self.value >= other.value
class MyHuffman():
def __init__(self):
self.chars = {}
self.tree = None
self.decodePosition = 0
def build(self,weights):
huffNodes = []
heapq.heapify(huffNodes)
for x,y in weights.items():
heapq.heappush(huffNodes,Node(y,x))
while len(huffNodes) > 1:
left = heapq.heappop(huffNodes)
right = heapq.heappop(huffNodes)
left.code = 1
right.code = 0
heapq.heappush(huffNodes,Node(left.value+right.value,left.data + right.data,left,right))
self.tree = huffNodes[0]
self.makeLookupTable(self.tree)
def makeLookupTable(self,node,bitCode=""):
codes = bitCode + str(node.code)
if node.left == None and node.right == None:
self.chars[node.data] = codes
else:
self.makeLookupTable(node.left,codes)
self.makeLookupTable(node.right,codes)
return self.chars
def encode(self,word):
bitString = ""
for x in range (0,len(word)):
if word[x] in self.chars:
for y,z in self.chars.items():
if word[x] == y:
bitString = bitString + z
return bitString
def decode(self,bitstring):
for x in bitstring:
if x != "0" and x != "1":
return None
dec = self.recursiveTraverseTree(self.tree,bitstring)
self.decodePosition=0
return dec
def recursiveTraverseTree(self,bitString,words=""):
if node.left == None and node.right == None:
words= words + str(node.data)
node = self.tree
if self.decodePosition < len(bitString):
if bitString[self.decodePosition] == "0":
self.decodePosition+=1
return self.recursiveTraverseTree(node.right,words)
elif bitString[self.decodePosition] == "1":
self.decodePosition+=1
return self.recursiveTraverseTree(node.left,words)
return words
下面运行一些测试 第一个测试工作正常,但第二个给出了 maxRecursion 深度错误
huff = MyHuffman()
freqs = {'z': 50,'j': 1,"'": 11,'a': 42,'d': 3,'l': 1,'f': 14,' ': 31,'i': 1,'w': 8,'s': 41,'r': 2,'k': 49,'b': 28,'q': 28,'p': 32,'g': 33,'v': 51,'c': 6,'h': 6,'m': 5,'y': 8,'o': 36,'t': 28,'u': 23,'n': 15}
b = huff.build(freqs)
word = "damn son"
bitstring = huff.encode(word)
decrypted = huff.decode(bitstring)
print(f"[{word}] -> [{bitstring}] -> [{decrypted}]")
#Outputs[damn son] -> [1000011001110000101000110010100010110001] -> [damn son]
word1 ="bgzqbbvkqpaawaoasczz nfq szbumq'vzmbvbknsvvqouapcpbzkvbgtbsggcohto p tzhytz kkutanbv ubsbaogasznr tzz pzzsgqfqpsnfugsktpuzztq s vkfzavokoogmvzgpk tagkz zaoz'vaqpqkvbuvqtsbzgf zk kuzasovhauoqwtvvvovko fvbwhzpvpkskouaupspstbvgsbszipqvvuvmuaspzna stvvk gu saaokggnmsvtspkvqvsahvozsawszfpws skgg bqkqu salg fovuknaknpupovafbovqssagpgbfkcuz gf ofgyrokasgc guabqzbtkosqzbzvspzwgnsyfhvoz akgo'htsovzpakabayffpkpkvqrpzzqogsfvvatsvqbaapozavuyovzpbzsz ppuzrqbq'jaq zuqhhpptvkguktcbkazsszsgvocppzptzzhtzgt b mkznz qqk avkmztzsbzkgrovkqsssb pvtvssoutssazasunaavgybffppqgqagbsa gqscwpno'pb qsknzagtu pztqfbmbztmtuzktvza gaovapkvav govpv oazg'qgrpyszvqqzvgvztbavsy pswurtauztkztavv zcqvzs gbt zgzosfvtpk'gyggbokt ktgukzgskfzf ntavpq bzazvtphvcfba knp'zg'vsyqtvuopz tvzks fn'boaakyvskgvgqggqz tknqbbbvskavkgqpskkkvapca rvzpkksvw'p spvhbzfgggzz'fopfsngoujykutkapbvtqzkkaanpogpnozohvqgfwkdpkvgdpouku v zpkkonuzks oznspqz'aszvnt v ytkcptstkftcknfksbkqszqht z wmpafzwf vkofvadvaqagqzpnzavvuzqkau nqobvggzp qv gup fokkbsoaqkoz svu uvzqzzpyfwuq ozszkzspkavsvta tgovt zpyqvpkzpbnvbsakkgvaktkqwukozp zskzr a aobzopg qtmkakk g nz vgagaktwv tptw bfqmsogzhhkpzwaza tokcbta kzzutvzk zvkunqoowako zabvvkqu'zb kp kvakvthgytvsvstpbvngvskgaqnfkokwozbztgszh'pgbopsgdnvzvozzgvsvgpvuzbuvkzat"
bitstring1 = huff.encode(word1)
decrypted1 = huff.decode(bitstring1)
print(f"[{word1}] -> [{bitstring1}] -> [{decrypted1}]")
#Gives maximum recursion depth error
解决方法
word1
的长度为 1260。霍夫曼码每个字母至少使用 1 位。因此,bitstring1
的长度至少为 1260 位。 decode
对解码的每一位递归一次,或至少 1260 次。这超过了 Python 的默认限制 1000,因此您会收到错误消息。
这是一个草图(未经测试),它在循环中重写 decode
并在递归中保持树搜索。
def decode(self,bitstring):
for x in bitstring:
if x != "0" and x != "1":
return None
pos = 0
size = len(bitstring)
dec = ""
while pos < size:
pos,word = self.decode_one(self.tree,bitstring,pos)
dec += word
self.decodePosition = 0
return dec
def decode_one(self,node,pos):
"""Return a tuple of the smallest unused position and the word"""
if node.left == None and node.right == None:
return pos,node.data
elif bitstring[pos] == "0":
return self.decode_one(node.right,pos + 1)
elif bitstring[pos] == "1":
return self.decode_one(node.left,pos + 1)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。