费诺编码 / Ferno Encoding

4月 30, 2024·
Junhong Liu
Junhong Liu
· 3 分钟阅读时长

此程序为费诺编码的Python实现,但此版本存在缺陷:每个编码符号出现的概率不能相同。该问题在第二个程序得到改进。

第一个程序

'''
All rights reserved by Liu Junhong
Reference books: 《信息论基础》
Completion time:2020-11-24
'''
#import numpy as np
#import pandas
#import time
import math
#import sys

#程序说明
print("-------------------<费诺编码>程序说明-------------------")
print("Designed by Junhong Liu:All rights reserved")
print("Reference books: 《信息论基础》、百度百科-费诺编码 (https://baike.baidu.com/item/%E8%B4%B9%E8%AF%BA%E7%BC%96%E7%A0%81)")
print("Completion time:2020-11-24")
print("Last modification time :2020-11-24")
print("--------------------------------------------------------")
print("\n")

#*******录入数据
N_num = float(input("请输入需要编码字符个数:"))
while(N_num <= 0 or (N_num % 1)):
    N_num = float(input("请输入正整数:"))
N_num = int(N_num)

Dict = {}
probability = 1


while(N_num > 0):
    N_num = N_num-1
    print("\n","------还需输入",N_num,"编码字符信息------")
    print("\n","请输入一个编码字符名:")
    name = str(input())
    Dict.setdefault(name)
    print("请输入小于",probability,"的对应编码字符概率:")
    value = float(input())
    probability = probability - value
    Dict[name] = value

#print(Dict)

#按概率排序
Dict_order=sorted(Dict.items(),key=lambda x:x[1],reverse=True)

#print(Dict_order)
#sys.exit(0)

#编码算法
name = []
value = []
#code = []

#truncation = 0 #保存截断位置
for i in Dict_order:
    name.append(i[0])
    value.append(i[1])
    
Fano_dict_value = {}.fromkeys(value,'')
#print(name)
#print(value)

value_copy = [value]
value_copy_copy = []

while(len(value_copy)>0):
    for k in value_copy:
        if len(k) == 2:
            Fano_dict_value[k[0]] = Fano_dict_value[k[0]] + '0'
            Fano_dict_value[k[1]] = Fano_dict_value[k[1]] + '1'
        else:
            for i in range(len(k)):
                a = sum(k[:i])
                b = sum(k[i:])
                c = sum(k[:(i+1)])
                d = sum(k[(i+1):])
                if abs(a-b)<abs(c-d):
                    if i == 1:
                        Fano_dict_value[k[0]] = Fano_dict_value[k[0]] + '0'
                        value_copy_copy.append(k[1:])
                        for h in k[1:]:
                            Fano_dict_value[h] = Fano_dict_value[h] + '1'
                    else:
                        value_copy_copy.append(k[:i])
                        value_copy_copy.append(k[i:])
                        for j in k[:i]:
                            Fano_dict_value[j] = Fano_dict_value[j] + '0'
                        for h in k[i:]:
                            Fano_dict_value[h] = Fano_dict_value[h] + '1'
                    break
    value_copy = value_copy_copy
    value_copy_copy = []

#输出结果
Fano_dict = dict(zip(name,Fano_dict_value.values()))
print(Fano_dict)

第二个程序

'''
All rights reserved by Liu Junhong
Reference books: 《信息论基础》
Completion time:2020-11-24
'''
import math

#程序说明
print("-------------------<费诺编码>程序说明-------------------")
print("Designed by 刘俊宏:All rights reserved")
print("Reference books: 《信息论基础》、百度百科-费诺编码 (https://baike.baidu.com/item/%E8%B4%B9%E8%AF%BA%E7%BC%96%E7%A0%81)")
print("Completion time:2020-11-24")
print("Last modification time :2020-11-25")
print("--------------------------------------------------------")
print("\n")

#*******录入数据
N_num = float(input("请输入需要编码字符个数:"))
while(N_num <= 0 or (N_num % 1)):
    N_num = float(input("请输入正整数:"))
N_num = int(N_num)

Dict = {}
probability = 1


while(N_num > 0):
    N_num = N_num-1
    print("\n","------还需输入",N_num,"编码字符信息------")
    print("\n","请输入一个编码字符名:")
    name = str(input())
    Dict.setdefault(name)
    print("请输入小于",probability,"的对应编码字符概率:")
    value = float(input())
    probability = probability - value
    Dict[name] = value


#按概率排序
Dict_order=sorted(Dict.items(),key=lambda x:x[1],reverse=True)

#编码算法
name = []
value = []
for i in Dict_order:
    name.append(i[0])
    value.append(i[1])
    
Fano_dict = {}.fromkeys(name,'')

value_copy = [value]
value_copy_copy = []
name_copy = [name]
name_copy_copy = []
while(len(value_copy)>0):
    for k in range(len(value_copy)):
        if len(value_copy[k]) == 2:
            Fano_dict[name_copy[k][0]] = Fano_dict[name_copy[k][0]] + '0'
            Fano_dict[name_copy[k][1]] = Fano_dict[name_copy[k][1]] + '1'
        else:
            for i in range(len(value_copy[k])):
                a = sum(value_copy[k][:i])
                b = sum(value_copy[k][i:])
                c = sum(value_copy[k][:(i+1)])
                d = sum(value_copy[k][(i+1):])
                if abs(a-b)<abs(c-d):
                    if i == 1:
                        Fano_dict[name_copy[k][0]] = Fano_dict[name_copy[k][0]] + '0'
                        value_copy_copy.append(value_copy[k][1:])
                        name_copy_copy.append(name_copy[k][1:])
                        for h in name_copy[k][1:]:
                            Fano_dict[h] = Fano_dict[h] + '1'
                    else:
                        value_copy_copy.append(value_copy[k][:i])
                        value_copy_copy.append(value_copy[k][i:])
                        name_copy_copy.append(name_copy[k][:i])
                        name_copy_copy.append(name_copy[k][i:])
                        for j in name_copy[k][:i]:
                            Fano_dict[j] = Fano_dict[j] + '0'
                        for h in name_copy[k][i:]:
                            Fano_dict[h] = Fano_dict[h] + '1'
                    break
    value_copy = value_copy_copy
    name_copy = name_copy_copy
    value_copy_copy = []
    name_copy_copy = []

#输出结果
print(Fano_dict)