python哈夫曼编码注意_哈夫曼编码问题

在这段代码中有不止一个奇怪之处;-),但我认为您的主要问题是:def __cmp__(self, a):

return cmp(self.code, a.code)

堆操作使用comparison方法对堆进行排序,但出于某种原因,您告诉它按当前代码长度对Node排序。几乎可以肯定的是,你想把他们的重量堆起来,对吗?哈夫曼编码就是这样工作的。在

^{pr2}$

对于其余的,很难理解,因为5个符号中有4个是相同的(4个0和1个1)。你怎么知道它是否有效?在

在循环内部,这是紧张的:lo, hi = sorted([heappop(tree), heappop(tree)])

考虑到对__cmp__的修复,这更简单:lo = heappop(tree)

hi = heappop(tree)

排序是没有意义的-总是弹出当前最小的元素。所以弹出两次,并且lo <= hi必须为真。在

我想多说些;-),但在这一点上,我对你最终要达到的目标感到困惑。如果您同意__cmp__应该被修复,那么进行更改并编辑问题,以使一些输入和输入都能得到您希望得到的确切输出。在

更多

关于:it gives the top nodes the longest codewords instead of the final leaves,

这不是一个“offby1”的事情,它更像是一个“向后”的事情;—)Huffman编码首先考虑权重最小的节点。节点从堆中弹出的时间越晚,权重越高,其代码的长度也应越短。但随着过程的进行,代码会变得更长。随着流程的进行,它们应该会变得越来越短。在

你不能在建树的时候这样做。事实上,在树构建过程完成之前,代码是不可知的。在

所以,我将给出一些工作代码,您可以根据自己的喜好进行修改,而不是猜测意图等。我将包括一个示例输入及其输出:from heapq import heappush, heappop, heapify

class Node(object):

def __init__(self, weight, left, right):

self.weight = weight

self.left = left

self.right = right

self.code = None

def __cmp__(self, a):

return cmp(self.weight, a.weight)

class Symbol(object):

def __init__(self, name, weight):

self.name = name

self.weight = weight

self.code = None

def __cmp__(self, a):

return cmp(self.weight, a.weight)

def encode(symbfreq):

# return pair (sym2object, tree), where

# sym2object is a dict mapping a symbol name to its Symbol object,

# and tree is the root of the Huffman tree

sym2object = {sym: Symbol(sym, w) for sym, w in symbfreq}

tree = sym2object.values()

heapify(tree)

while len(tree) > 1:

lo = heappop(tree)

hi = heappop(tree)

heappush(tree, Node(lo.weight + hi.weight, lo, hi))

tree = tree[0]

def assigncode(node, code):

node.code = code

if isinstance(node, Node):

assigncode(node.left, code + "0")

assigncode(node.right, code + "1")

assigncode(tree, "")

return sym2object, tree

i = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]

s2o, t = encode(i)

for v in s2o.values():

print v.name, v.code

打印出:a 010

c 00

b 011

e 11

d 10

所以,正如我们所希望的那样,权重最高的符号拥有最短的代码。在

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值