36元霍夫曼编码python实现

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("输入概率分布不规范")
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值