香农编码,费诺编码,赫夫曼编码(python实现)
开始参考了网上其他人的代码,但后来都发现要么代码有错误,要么输出结果不符合自己的预期,于是就重新实现了一下,代码仍存在一些小问题,但是能够满足作业要求,重要的是看懂思路,然后按照自己的想法去实现
代码存在的问题:
- 香农编码和费诺编码起始的符号及其概率都已给出并且做了初步处理,有想法的可以改成用户自定义输入
- 费诺编码的实现借助了字典和递归,但是如果初始输入的概率集中存在相同的key(也就是概率集中存在相同概率),那么字典update()方法的覆盖特性会使两个相同概率对应的码字合并(因为事情比较多,就没有改代码,有带佬知道怎么解决的话求帮助)
- 赫夫曼编码借鉴了别人的代码,初始数据是用户自定义输入的
香农编码
Code:
import math
p = [0.4, 0.3, 0.2, 0.1] # 信源符号概率递减排列
p_next = [0, 0.4, 0.7, 0.9] # 概率累加和
k = [] # 对应码长
length_k = 0 # 平均码长
H = 0 # 信源熵
def code_length():
for i in range(len(p)):
k.append(int(math.log(p[i], 2) * (-1) + 0.99))
print('码长:{}'.format(k))
def average_length():
global length_k
for i in range(len(p)):
length_k += k[i] * p[i]
# print(round(length_k, 1))
print("平均码长为:{:.3}(bit/sign)".format(length_k))
# 将十进制小数转为二进制小数
def int_to_bin(px):
b = []
while True:
px *= 2
b.append(1 if px>=1 else 0)
px -= int(px)
if px == 0:
for i in range(len(p)):
if len(b) != k[i]:
b.append('0'*(k[i]-len(b)))
break
return b
def codeword():
code = [] # 对应码字
for i in range(len(p)):
e = ''
for j in range(k[i]):
e += str(int_to_bin(p_next[i])[j])
code.append(e)
print('码字:{}'.format(code))
def Hx()