python面向对象实现算术编码

算术编码:

①原理: 将待编码的数据序列用[0, 1)之间的一个小数来表示,数据序列越长,小数点后的位数就越多,所需的二进制位数也就越多。

②编码过程:
{StartN=StartB+LeftC×LEndN=StartB+RightC×L\left\{ \begin{array}{l} Star{t_N} = Star{t_B} + Lef{t_C}{\rm{ \times }}L\\ En{d_N} = Star{t_B} + Righ{t_C}{\rm{ \times }}L \end{array} \right. {StartN​=StartB​+LeftC​×LEndN​=StartB​+RightC​×L​

下标N:新的(NEW)、B:前一个(BEFORE)、C:当前的(CURRENT)。下标N:新的(NEW)、B:前一个(BEFORE)、C:当前的(CURRENT)。 下标N:新的(NEW)、B:前一个(BEFORE)、C:当前的(CURRENT)。

StartN是新区间的起始位置、EndN是新区间的结束位置、StartN是前一区间的起始位置Star{t_N}是新区间的起始位置、En{d_N}是新区间的结束位置、Star{t_N}是前一区间的起始位置 StartN​是新区间的起始位置、EndN​是新区间的结束位置、StartN​是前一区间的起始位置

LeftC是当前编码区间的左端点,RightC是当前编码区间的右端点。Lef{t_C}是当前编码区间的左端点,Righ{t_C}是当前编码区间的右端点。 LeftC​是当前编码区间的左端点,RightC​是当前编码区间的右端点。

③解码过程: 第一个符号判断在那个编码区间内

以后的符号:
(code−leftB)/pi∈[lefti,righti)令code等于前述结果,迭代。(code - lef{t_B})/pi \in [lef{t_i},righ{t_i}) 令code等于前述结果,迭代。 (code−leftB​)/pi∈[lefti​,righti​)令code等于前述结果,迭代。

code为当前计算结果,leftB为上一编码区间的左端点,pi为上一编码区间对应概率,[lefti,righti)是判断属于哪个编码区间。code为当前计算结果,lef{t_B}为上一编码区间的左端点,pi为上一编码区间对应概率,[lef{t_i},righ{t_i})是判断属于哪个编码区间。 code为当前计算结果,leftB​为上一编码区间的左端点,pi为上一编码区间对应概率,[lefti​,righti​)是判断属于哪个编码区间。

程序

# 江南大学物联网18级——MH
from decimal import Decimal as dm# 定义实体类,实体类存储符号和其对应的概率和编码区间,这是利用python面向对象编程~
class SymbolAndProbability:symbol = 'x'probability = '0'left = '0'right = '0'# 构造函数~def __init__(self, symbol, probability, left, right):self.symbol = symbolself.probability = probabilityself.left = leftself.right = right# 算术编码~
def arithmetic_code(symbol_str, arr):# 将输入字符串转化为数组count_fIrst = int(symbol_str.count(arr[1].symbol))symbol_arr = []for index in range(0, len(symbol_str)):symbol_arr.append(symbol_str[index])# 初始化,length为 1 ,start_b 为 0length = '1.0'start_b = '0'print("\n>>>算术编码过程如下:")for x_index in range(0, len(symbol_arr)):# 和字典匹配,如果匹配到,就编码~for y_index in range(1, len(arr)):if symbol_arr[x_index] == arr[y_index].symbol:start_n = dm(start_b) + dm(arr[y_index].left) * dm(length)end_n = dm(start_b) + dm(arr[y_index].right) * dm(length)length = dm(end_n) - dm(start_n)start_b = dm(start_n)print("symbol", symbol_arr[x_index], "startN", format(start_n, '.30f'), "endN", format(end_n, '.30f'), "L", format(length, '.30f'))break# 匹配不到说明输入符号有问题,退出!if y_index == len(arr) - 1 and symbol_arr[x_index] != arr[y_index].symbol:print(">>>error! 输入符号中有字典中未存储符号")exit(0)# 返回区间左端点作为编码结果return dm(start_n), count_fIrst# 算术解码
def arithmetic_decode(end_code, arr, count_First):print("\n>>>算术解码为:")str_for_count = ''for x_index in range(1, len(arr)):if dm(arr[x_index].left) <= dm(end_code) < dm(arr[x_index].right):last = x_indexprint(arr[x_index].symbol, end='')if arr[x_index].symbol == arr[1].symbol:str_for_count += arr[x_index].symbolbreakwhile dm(end_code) != dm('0'):end_code = dm((dm(end_code) - dm(arr[last].left)) / dm(dm(arr[last].right) - dm(arr[last].left)))for x_index in range(1, len(arr)):if dm(arr[x_index].left) <= dm(end_code) < dm(arr[x_index].right):last = x_indexprint(arr[x_index].symbol, end='')if arr[x_index].symbol == arr[1].symbol:str_for_count += arr[x_index].symbolbreakif str_for_count.count(arr[1].symbol) < count_First:print(arr[1].symbol*(count_First - str_for_count.count(arr[1].symbol)))return# 打印输入内容
def class_print_all(arr):print("\n>>>输入符号,对应概率和编码区间为:")for x_index in range(1, len(arr)):print("symbol:'", arr[x_index].symbol, "' probability:", arr[x_index].probability, "  区间→[", arr[x_index].left, ",", arr[x_index].right, ")")# 输入概率和符号
def symbol_probability_input():# split(‘str’)函数会将字符串str切掉,如果两个str中间没有非空字符(strstr),则''空字符为分割结果,利用此原理,输入空格。print(">>>输入符号,以空格隔开\n[注]符号中有空格,例如要输入[' ','a',' ','b',' '],应该这样输入:_a__b_\n    即输入符号“空格”时,它和前面字符以空格隔开,后面则不需要")symbol = input().split(' ')symbol_string = ''# 如果是''空字符,就将其变为' '空格for str_index in range(0, len(symbol)):if symbol[str_index] == '':symbol[str_index] = ' 'symbol_string += symbol[str_index]# 检查输入符号是否重复?for rpt_index in range(0, len(symbol_string)):if symbol_string.count(symbol[rpt_index]) > 1:print(">>>error!输入了重复符号")exit(0)probability = input(">>>输入概率,以空格隔开\n").split(' ')# 检查概率完备性 及 输入情况sum_p = 0for x_index in range(0, len(probability)):sum_p += dm(probability[x_index])if abs(sum_p - 1) > 1e-4:print("error! 概率不具有完备性!")exit(0)if len(symbol) != len(probability):print("error! 输入符号数目与概率数目不匹配")exit(0)arr = []init = SymbolAndProbability(symbol='zero', probability='0', left='0', right='0')# arr第一个元素(下标为0)存放有关初始化的操作arr.append(init)for x_index in range(1, len(probability) + 1):# 当前的符号,准备存入实体类syb = symbol[x_index - 1]# 当前的概率,准备存入实体类pb = probability[x_index - 1]# 当前的区间左端点为前一区间的右端点,准备存入实体类left = arr[x_index - 1].right# 实例化类new_element = SymbolAndProbability(symbol=syb, probability=pb, left=left, right=dm(left) + dm(pb))arr.append(new_element)return arrif __name__ == '__main__':# 输入符号和概率array_sy_pb = symbol_probability_input()# 打印具体信息class_print_all(array_sy_pb)# 获得算术编码结果code_end, count_first = arithmetic_code(str(input("\n输入字符串(不需要使用空格隔开)\n")), array_sy_pb)# 算术编码解码arithmetic_decode(code_end, array_sy_pb, count_first)

python面向对象实现算术编码相关推荐

  1. Python面向对象基础:编码细节和注意事项

    在前面,我用了3篇文章解释python的面向对象: 面向对象:从代码复用开始 面向对象:设置对象属性 类和对象的名称空间 本篇是第4篇,用一个完整的示例来解释面向对象的一些细节. 例子的模型是父类Em ...

  2. 基于Python的算术编码的设计与实现

    基于Python的算数编码实验 一.实验目的 给出算术编码实现的详细原理. 编制编解码程序 设计并实现自适应算术编码(选做) 二.实验环境 硬件环境:windows 10; VScode 编程语言:p ...

  3. 5.3 Python图像处理之图像编码-算术编码

    5.3 Python图像处理之图像编码-算术编码 文章目录 5.3 Python图像处理之图像编码-算术编码 1 算法原理 2 代码 3 效果 1 算法原理 算术编码在图像数据压缩标准(如JPEG,J ...

  4. 算术编码原理及其python实现

    目录 1. 原理部分: 2. 香农界理论分析: 3. 代码实现: 4.实验结果 1. 原理部分: 原理部分参考什么是算术编码 一个从信源序列到不可压缩二元序列的一个可逆映射,假设序列{X1-Xn}\{ ...

  5. 【Python】学习笔记总结2(Python面向对象)

    文章目录 二.Python面向对象 1.类(Class) 1.1.定义类 1.2.类属性 1.3.实例属性 1.3.1.内部添加 1.3.2.外部添加 1.4.实例方法 1.5.类方法 1.6.静态方 ...

  6. 【Python面试】 说说Python面向对象三大特性?

    往期面试题: 谈谈对 Python 和其他语言的区别? 说说 Python 解释器种类以及特点? 说说4种常用编码的区别? 废话不多说,开始今天的题目: 问:说说Python面向对象三大特性? 答:P ...

  7. python面向对象程序设计实训学生自我总结_Python面向对象程序设计示例小结

    本文实例讲述了Python面向对象程序设计.分享给大家供大家参考,具体如下: 示例1: #encoding:utf-8 '''example 1 class test: def __init__(se ...

  8. python 面向对象的封装_Python面向对象封装操作案例详解

    本文实例讲述了Python面向对象封装操作.分享给大家供大家参考,具体如下: 目标 封装 小明爱跑步 存放家具 01. 封装 封装 是面向对象编程的一大特点 面向对象编程的 第一步 ―― 将 属性 和 ...

  9. 《Python面向对象编程》读后感

    [b]一.Python简介[/b] 创始人? 吉多·范罗苏姆(Guido van Rossum)(社区人称仁慈的独裁者) 创建原因? 1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决 ...

  10. Python零基础速成班-第10讲-Python面向对象编程(下),Property属性、特殊方法、设计模式、链表应用

    Python零基础速成班-第10讲-Python面向对象编程(下),Property属性.特殊方法.设计模式.链表应用 学习目标 面向对象编程 接上一讲:Property属性.特殊方法.设计模式 面向 ...

最新文章

  1. Csharp关键字----delegate(委托)
  2. 转PHP5+APACHE2.2配置
  3. LaneCat网猫软件
  4. PAT甲级题目翻译+答案 AcWing(贪心)
  5. 11-Qt6 QByteArray字节数组类
  6. HTTP和HTTPS的了解
  7. Linux系统学习之 三:新手必须掌握的Linux命令3
  8. 第二期冲刺站立会议个人博客6(2016/5/30)
  9. 语言技巧——scanf读入多行字符串
  10. Struts2--类型转换
  11. 133道Java面试题及答案(面试必看)
  12. itext pdf 基本使用实战
  13. mac 误删引导分区
  14. 线性代数05 齐次/非齐次线性方程组的具体解集
  15. Eclipse的Maven创建
  16. unity实现简单fps游戏功能
  17. 自动控制原理实验一——离散控制系统建模和仿真
  18. 内部总线、系统总线、外部总线区别
  19. 2014年如何找到SEO流量的突破口
  20. vmware的vmdk格式虚拟机转换为qcow2格式

热门文章

  1. ASC加密解密(笔记)
  2. asc 点阵数组和计算认识
  3. WinCE 5.0下的鼠标键盘驱动分析
  4. idea springboot学习笔记
  5. c语言 除法优化,【小课堂】汇编级除法优化
  6. 自己编写DLL文件——注册——VB工程引用——标准EXE调用(含例子)
  7. 往linux内核添加ch341,linux 4.1 usb驱动之usb_serial芯片ch341
  8. 中国联通 光猫 吉比特 G-140W-UG 管理员 账号密码
  9. 使用PHP控制MODBUS-RTU设备
  10. 小米路由器 R1D 可用 java JRE openjdk