【问题标题】:Decoding a Huffman Tree from a String从字符串中解码霍夫曼树
【发布时间】:2017-08-18 14:43:58
【问题描述】:

我正在研究将霍夫曼树存储在文件中的有效方法,以允许解码器重建霍夫曼树并正确解码文件。目前,我已经创建了一个函数来创建给定频率的霍夫曼编码。

看到Efficient way of storing Huffman tree,于是写了一个递归函数来模仿帖子回答中的递归函数:

>>> huffman = [(b'A', '00'), (b'C', '01'), (b'E', '10'), (b'B', '110'), (b'D', '111')]
>>> write(hf)
b'001A1C01E01B1D'

在帖子中,答案使用对象来包含节点叶。但是,我想将字符串直接解码为元组列表,就像上面的 huffman 变量一样。我对此进行了尝试,并提出了以下功能,该功能很有效:

def read(p):
    if p[0] == "1":
        x = p[1]
        p = p[2:]
        if len(p) == 0:
            c = [(x, "")]
        else:
            b = read(p)
            for a in range(len(b)):
                b[a] = (b[a][0], "1" + b[a][1])
            c = [(x, "0")] + b
        return c
    if p[0] == "0":
        c = read(p[1:])
        return c

函数在调用时返回 this:

>>> read("001C1A01E01D1B")
[('C', '0'), ('A', '10'), ('E', '110'), ('D', '1110'), ('B', '1111')]

这显然和上面的原始字典huffman不一样。

如何在不使用节点类的情况下递归解码霍夫曼树字典,并获得原始字典?

【问题讨论】:

  • 您的write() 函数没有完全按预期工作。即write([("A", 6), ("B", 1), ("C", 6), ("D", 2), ("E", 5)]) 在 Python 3 中导致 if a[1][0] == "0": -> TypeError: 'int' object is not subscriptable,在 Python 2 中导致 TypeError: 'int' object has no attribute '__getitem__'(它们基本上都在抱怨同一个问题)。
  • edit你的问题并提供一个MCVE(见How to create a Minimal, Complete, and Verifiable example所以人们不必猜测。
  • @martineau 同样,在您的评论中提供编辑问题的链接有点粗鲁。我对 SO 足够熟悉,知道我要去哪里编辑问题。
  • 别那么敏感。以 43 的代表,我为什么要假设你有很多这样的经验。 MCVE is 也适用于此处,因为您基本上是在问“为什么这不起作用”。如果您知道这一点,请原谅我——但关闭此类问题的原因之一是“寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定问题或错误以及 在问题本身中重现它所需的最短代码。*”(强调我的)

标签: python string dictionary recursion huffman-code


【解决方案1】:

首先,您传递给read() 函数的字符串'001C1A01E01D1B' 与您在上面的解释中显示的不同,也不是引用页面'001A1C01E01B1D' 中使用的字符串。解决这个问题,您的代码会产生更好的输出,但仍然不正确:

[('A', '0'), ('C', '10'), ('E', '110'), ('B', '1110'), ('D', '1111')]

就解码而言,让递归为我们完成工作:

class HuffmanSyntaxError(Exception):
    ''' Raised due to incorrect or extra encoded string elements '''

def read_recursive(string, code=''):
    if string[0] == "0":
        first, string = read_recursive(string[1:], code + "0")
        second, string = read_recursive(string, code + "1")

        return [*first, *second], string

    if string[0] == "1":
        return [(string[1], code)], string[2:]

    raise HuffmanSyntaxError(string)  # unknown option

def read(string):
    array, string = read_recursive(string)

    if string:  # left over input
        raise HuffmanSyntaxError(string)

    return array

print(read("001A1C01E01B1D"))

例程的递归版本将字符串的未解析剩余部分作为第二个结果返回。前端函数将其移除,返回所需的结果:

% python3 test.py
[('A', '00'), ('C', '01'), ('E', '10'), ('B', '110'), ('D', '111')]
%

【讨论】:

    猜你喜欢
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多