22161: 哈夫曼编码树
http://cs101.openjudge.cn/practice/22161/
根据字符使用频率(权值)生成一棵唯一的哈夫曼编码树。生成树时需要遵循以下规则以确保唯一性:
选取最小的两个节点合并时,节点比大小的规则是:
- 权值小的节点算小。权值相同的两个节点,字符集里最小字符小的,算小。
例如 ({'c','k'},12) 和 ({'b','z'},12),后者小。
- 合并两个节点时,小的节点必须作为左子节点
- 连接左子节点的边代表0,连接右子节点的边代表1
然后对输入的串进行编码或解码
输入
第一行是整数n,表示字符集有n个字符。 接下来n行,每行是一个字符及其使用频率(权重)。字符都是英文字母。 再接下来是若干行,有的是字母串,有的是01编码串。
输出
对输入中的字母串,输出该字符串的编码 对输入中的01串,将其解码,输出原始字符串
样例输入
3
g 4
d 8
c 10
dc
110样例输出
110
dc提示: 数据规模很小,不用在乎效率
来源: 郭炜
python
import heapq
class Node:
def __init__(self, weight, char=None):
self.weight = weight
self.char = char
self.left = None
self.right = None
def __lt__(self, other):
if self.weight == other.weight:
return self.char < other.char
return self.weight < other.weight
def build_huffman_tree(characters):
heap = []
for char, weight in characters.items():
heapq.heappush(heap, Node(weight, char))
while len(heap) > 1:
left = heapq.heappop(heap)
right = heapq.heappop(heap)
merged = Node(left.weight + right.weight)
merged.left = left
merged.right = right
heapq.heappush(heap, merged)
return heap[0]
def encode_huffman_tree(root):
codes = {}
def traverse(node, code):
if node.char:
codes[node.char] = code
else:
traverse(node.left, code + '0')
traverse(node.right, code + '1')
traverse(root, '')
return codes
def huffman_encoding(codes, string):
encoded = ''
for char in string:
encoded += codes[char]
return encoded
def huffman_decoding(root, encoded_string):
decoded = ''
node = root
for bit in encoded_string:
if bit == '0':
node = node.left
else:
node = node.right
if node.char:
decoded += node.char
node = root
return decoded
# 读取输入
n = int(input())
characters = {}
for _ in range(n):
char, weight = input().split()
characters[char] = int(weight)
#string = input().strip()
#encoded_string = input().strip()
# 构建哈夫曼编码树
huffman_tree = build_huffman_tree(characters)
# 编码和解码
codes = encode_huffman_tree(huffman_tree)
strings = []
while True:
try:
line = input()
if line:
strings.append(line)
else:
break
except EOFError:
break
results = []
#print(strings)
for string in strings:
if string[0] in ('0','1'):
results.append(huffman_decoding(huffman_tree, string))
else:
results.append(huffman_encoding(codes, string))
for result in results:
print(result)