from fractions import Fraction def sort(lst): for sort_rounds in range(len(lst)-1): for comp_rounds in range(len(lst) - sort_rounds - 1): if lst[comp_rounds].probability > lst[comp_rounds+1].probability: temp = lst[comp_rounds] lst[comp_rounds] = lst[comp_rounds + 1] lst[comp_rounds + 1] = temp return lst#冒泡排序实现概率节点的排序 def sort_lst(lst): for sort_rounds in range(len(lst)-1): for comp_rounds in range(len(lst) - sort_rounds - 1): if lst[comp_rounds] < lst[comp_rounds+1]: temp = lst[comp_rounds] lst[comp_rounds] = lst[comp_rounds + 1] lst[comp_rounds + 1] = temp return lst#冒泡排序实现概率的排序 #节点类 class Tree_Node: def __init__(self, probability, r):#r是符号数,probabilitys是概率 self.probability = probability self.parent = None self.lefttoright = [None] * r#创建r个子节点 #每一个节点赋值,调用Tree_Node类默认方法初始化 def set_probability(probabilities,r): tree_nodes = [Tree_Node(probability,r) for probability in probabilities] return tree_nodes #创建霍夫曼树 def huffman_tree(tree_nodes,r): nodes_huf = tree_nodes[:] node_lst = [None] * r while len(nodes_huf) > 1: min_rp_sum = 0 nodes_huf=sort(nodes_huf) #自底向上构造树 for i in range(r): node_lst[i] = nodes_huf.pop(0) min_rp_sum = min_rp_sum+node_lst[i].probability node_parent = Tree_Node(min_rp_sum,r) for k in range(r): node_parent.lefttoright[k] = node_lst[k]#将最小的r个节点给该节点的父节点的第k个子节点 node_lst[k].parent = node_parent#为r个最小概率节点赋予父节点 nodes_huf.append(node_parent) nodes_huf[0].parent = None return nodes_huf[0] #概率之和1 #霍夫曼编码 def huffman_encoding(tree_nodes, node_huf,r): codes = [''] * len(tree_nodes) code_sign = [str(n) for n in range(10)] + [chr(ord('A') + n) for n in range(26)] for i in range(len(tree_nodes)): node_tmp = tree_nodes[i] while node_tmp != node_huf: for m in range(r): if node_tmp.parent.lefttoright[r-1-m] == node_tmp: codes[i] = code_sign[m] + codes[i] #从底向上查找 node_tmp = node_tmp.parent return codes r = int(input("请输入 r 的值: ")) # 输入概率分布,支持分数输入 input_probabilities = input("请输入概率分布(请用空格分隔): ").split() # 将分数转换为浮点数 probabilities = [float(Fraction(fraction)) for fraction in input_probabilities] if any('/' in fraction for fraction in input_probabilities): print('信源概率空间->{0}'.format(input_probabilities)) else: print('信源概率空间->{0}'.format(probabilities)) print('概率空间的和->{0}'.format(sum(probabilities))) probabilities = sort_lst(probabilities) if abs(1.0-sum(probabilities))<0.00001: theta = 1 q = 1 N_p = len(probabilities) #计算q值,q=(r-1)theta+1 while q < N_p: q = (r - 1) * theta + r theta = theta + 1 #增加q-N_p个信源符号 for i in range(q-N_p): probabilities.append(0) print('满足编码规则的信源符号数即q值->{0}'.format(q)) tree_nodes = set_probability(probabilities,r) nodes_huf = huffman_tree(tree_nodes,r) codes = huffman_encoding(tree_nodes, nodes_huf,r) print("概率和码字—>") for w in range(len(probabilities)): #if probabilities[w]!=0:#此行注释掉可以输出补充的信源符号 if any('/' in fraction for fraction in input_probabilities): print('{0} → {1}'.format(input_probabilities[w], codes[w])) else: print('{0} → {1}'.format(probabilities[w], codes[w])) else: print("输入概率分布不规范")
36元霍夫曼编码python实现
最新推荐文章于 2024-07-21 16:33:09 发布