否则他会怒气冲天,把你的房子炸毁!
那完全无关紧要。这个挑战实际上与霍夫曼编码有关。要点是给定文本中字符的频率被用来使其表示更短。换句话说,假设我们的字母是a
通过z
和空格。那是27个字符。它们中的每一个都可以仅用5位进行唯一编码,因为5位有足够的空间容纳32个字符。但是,在许多情况下(例如英语或一般语言),某些字符比其他字符更频繁。对于更频繁的字符,我们可以使用较少的位,对于较不频繁的字符,我们可以使用更多的位。如果做对了,总体上可以节省位数,并且仍然可以唯一地重建原始文本。
让我们以“这个问题与霍夫曼编码有关”为例。该文本的长度为37个字符,通常为37 * 8 = 296位,但是如果每个字符仅使用5位,则只有37 * 5 = 185位。记住这一点。
这是文本中每个字符及其频率的(排序)表,从最频繁到最不频繁(其中_代表空格)排序:
_ 5
i 4
n 3
o 3
s 3
t 3
u 3
a 2
f 2
h 2
b 1
c 1
d 1
e 1
g 1
m 1
q 1
相关的最佳编码可以是:
_ 101
i 011
n 1100
o 1101
s 1110
t 1111
u 001
a 10011
f 0001
h 0101
b 00000
c 00001
d 01000
e 01001
g 10000
m 10001
q 10010
应当立即清楚的是,与每个字符仅使用5位相比,这将是更好的编码。让我们找出更好的方法!
145位,而185 位!这样可以节省40位,或仅节省20%以上!(当然,这是假定有关该结构的信息可用于解码。)这种编码是最佳的,因为通过更改任何字符的表示都不能丢掉更多的位。
任务
- 用一个参数编写程序或函数,该参数可以...
- 接受来自STDIN(或等效参数)的输入或作为单个参数。
- 输出上述最佳霍夫曼编码,并按频率对字符进行排序(频率类内的顺序无关紧要)。
- 您可以假定输入中的字符限制为ASCII范围
32..126
和换行符。 - 您可能会假设输入的字符数不超过10,000个(理论上,理想情况下,输入应无限制)。
- 您的代码应相当快地完成。上面给出的示例在最坏的情况下应该不会超过一分钟左右。(这是为了排除蛮力。)
- 得分以字节为单位。
例子
x
---
x 0
xxxxxxxxx
---
x 0
xxxxxxxxy
---
x 0
y 1 (these may be swapped)
xxxxxyyyz
---
x 0
y 10
z 11
uuvvwwxxyyzz
--- (or)
u 000 000
v 001 001
w 100 010
x 101 011
y 01 10
z 11 11
this question is about huffman coding
---
101
i 011
n 1100
o 1101
s 1110
t 1111
u 001
a 10011
f 0001
h 0101
b 00000
c 00001
d 01000
e 01001
g 10000
m 10001
q 10010
编码愉快!
请注意,这个相似的问题是紧密相关的,甚至是重复的问题。但是,到目前为止,关于Meta 的共识是,较旧的应该被认为是Meta的副本。
this question is about huffman coding
,我计算的位数为145,而不是