参考博客
https://blog.csdn.net/qq_33126189/article/details/104329374
值得一提的是,原博客编码生成的十进制小数取得是区间的最左端。
可能有些不妥,我将它改成了区间中值。
并改动了判断译码结束的方式,不需要再预先知道原信号有多少位符号。通过预先约定停止位“!”来确定何时停止译码
题目来源于 数据压缩与编码第二次实验
def get_dict_from_singal():#生成信源各符号概率的字典
singal_dict = {}
singal_dict['A'] = (0, 0.2)
singal_dict['B'] = (0.2, 0.3)
singal_dict['C'] = (0.3, 0.4)
singal_dict['D'] = (0.4, 0.7)
singal_dict['E'] = (0.7, 0.9)
singal_dict['!'] = (0.9, 1)
return singal_dict
def encoder(singal, singal_dict):#编码
Low = 0
High = 1
for s in singal:
CodeRange = High - Low#第N次编码时的概率区间
High = Low + CodeRange * singal_dict[s][1]
Low = Low + CodeRange * singal_dict[s][0]
return (Low+High)/2.0#取区间中值
def decoder(encoded_number, singal_dict):#译码
singal = []
FLAG=1#判断是否停止译码标志位
while FLAG:
for k, v in singal_dict.items():
if v[0] <= encoded_number < v[1] :
if v[0]!=0.9:
singal.append(k)
range = v[1] - v[0]
encoded_number -= v[0]
encoded_number /= range
elif v[0]==0.9:#检测到停止位“!”标志位置零,停止译码
FLAG =0
break
return singal
def main():
singal_dict = get_dict_from_singal()
singal = 'DEADBC!DEA'
ans = encoder(singal, singal_dict)
print(ans)
singal_rec = decoder(ans, singal_dict)
print(singal_rec)
if __name__ == '__main__':
main()
要说的都在注释里