我目前正在python中实现霍夫曼编码,我已经完成了它,但我想提高它的效率。
这是我用来获取原始文件内容的方法
def getDecodedFile(self, text, codes):
code = ""
origin = []
for ch in text:
code += ch
if code in codes:
origin.append(codes[code])
code = ""
bCodes = bytes(origin)
return bCodes
text
大字符串是codes
是霍夫曼代码的字典(Key是代码的字符串,值是0到255之间的int)
我尝试使用''.join(somelist)
代替code += ch
但结果却慢了。目前,使用len(text) = 13972363
执行此方法需要3秒钟,最短代码长度为6
数据示例:
text = "0100101110111"
codes = {'0': 65, '100': 66, '101': 67, '110': 68, '111': 69}
这将导致origin = [65,66,67,68,69]
我很感激任何使我的代码有效的建议。
答案 0 :(得分:2)
据我所知,你可以做的一件事就是当你这样做时:
code += ch
if code in codes:
origin.append(codes[code])
code = ""
具体而言,每次修改if code in codes:
时都会检查code
。例如,对于长度为 k 的代码,您将最终执行O(1 + 2 + 3 + ... + k )= O(0.5 * < em> k * k +1)= O( k ²)此处的操作。相反,您应该通过构建一个霍夫曼树并在树上执行单个O( k )遍历来解码您的代码(从根目录开始,并读取单个1或1)来预处理codes
每次0并沿着相应的子边缘向下;一旦你按下一个字母,在解码的消息中输出它并移回到树的根部)。这不仅明确节省了支票if code in codes:
的时间复杂度,而且还避免了每次执行code
时重建字符串code += ch
。
除此之外,我不确定你是否可以进一步优化。我想知道将每个单独的解码字母转换为byte
并附加到输出列表是否会更快,而不是将字母解码为列表然后通过bytes(origin)
转换列表?
答案 1 :(得分:2)
最大的性能提升将来自使用像trie这样的东西存储你的霍夫曼树。这将允许您一次下降一个级别,这将消除字符串连接或重复检查存在的需要。