c++实现几种模式的算术编码的编码和译码(固定模式,自适应模式,基于上下文的多阶自适应算术编码,完全统计模型)(信息论基础与编码)

自适应算术编码与完全统计模型算术编码算术编码(Arithmetic Coding)固定模式AC自适应算术编码操作方法代码基于上下文的多阶自适应算术编码(CABAC,H.264编码标准)完全统计模型算术编码操作方法代码算术编码(Arithmetic Coding)算术编码是图像压缩的主要算法之一。 是一种无损数据压缩方法,也是一种熵编码的方法。和其它熵编码方法不同的地方在于,其他的熵编码方法通常是把输入的消息分割为符号,然后对每个符号进行编码,而算术编码是直接把整个输入的消息编码为一个数,一个满足(0.0
摘要由CSDN通过智能技术生成

算术编码(Arithmetic Coding)

算术编码是图像压缩的主要算法之一。 是一种无损数据压缩方法,也是一种熵编码的方法。和其它熵编码方法不同的地方在于,其他的熵编码方法通常是把输入的消息分割为符号,然后对每个符号进行编码,而算术编码是直接把整个输入的消息编码为一个数,一个满足(0.0 ≤ n < 1.0)的小数n。[^1]
算术编码是将一个符号序列表示成0和1之间的一个间隔(interval),并用该间隔内的一个浮点小数表示,再将该小数转换成为二进制数,符号序列越长,对应的间隔越小,表示这一间隔的二进制位数就越多。

固定模式AC

题目:设信源可能输出的符号是26个字母,且每个字母出现的概率为:a, b, c, d, e, f 均为0.1,其它是等概的,试编写程序可以对任意字母序列(如presentation)进行固定模式的算术编码,并进行相应的译码。

自适应算术编码

操作方法

自适应算术编码即每输入一个字符就实时调整一次字符出现概率,按照此概率进行算术编码,循环。

步骤:
想象一个袋子里装着一些小球,每种字符相当于一个不同颜色的小球,最初,每种小球被摸中的概率都相等:
1.从输入流中每读取一个字符 ,就对该符号进行算术编码;
2.向袋中投入代表该种字符的小球,小球总数增加1,重新计算频率;
3.循环下去,每读一个字符就更新一次频率,进行算术编码。

问题和解答

1.wireeeee和wireless计算出来的编码长度哪个更短?为什么?
答:wireeeee更短。输入的字符串排列越有个性,编码越短。
2. 讲讲decord函数是怎么实现的。
答:先将编码出来的字符串转换为十进制数,然后概率初始化,再搜索该数所在区间,计算出新的区间,将temp转换成字母,译出字母再存入数组,循环就能实现译码。
3.为什么分数组序号=0和!=0的情况?
答:用io输入输出流的getline()获取的数组首位元素不能用于正则表达式,a[0]=‘ ’,必须分开讨论;也有其他解决办法,使用其他获取数组元素的方式。

算法流程图

自适应算术编码流程图

代码

题目要求:设信源可能输出的符号是26个字母,且每个字母出现的概率未知,试编写程序可以对任意字母序列(如presentation)进行自适应模式的算术编码,并进行相应的译码。(采用 8个字符一组,用空格或者回车作为间隔。即输入的字符串超过8位时,以8个为一组进行编码,相邻两组之间的记忆性取消。)

/****************** 自适应算术编码 **********************/
#include<cmath>
#include<string>
#include<iostream>
#include<iomanip>
using namespace std;
double proc[] = {
    1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,
				1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,
				1.0,1.0,1.0,1.0,1.0,1.0 };
double proc_sum = 26;
double probability[] = {
    1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0,1.0/26.0 };
double  areaBegin, areaEnd;
int cord[1000];
double cordLength;
char str[1000], newstr[1000];
int strLength = 0;  //字符串总长度
int num = 0;  //计数
int rowLength = 0;  //每行长度
double result;

bool readdat()
{
   
	cout<<"*********** 自适应模式 ***********\n";
	cout<<"请输入字符串(a--z): \n";

	//%s格式用来输入一个字符串,通过空格和换行来识别一个字符串的结束。也就是说使用%s格式输入并保存到字符数组中的字符串是不含空格的。
	//scanf("%s", str);
//	cin.getline(str, 1000, '\n');

	cin.getline(str, 1000);
	while (str[strLength] != '\0')
		strLength++;
	cout << "字符总长度:"<<strLength << endl;
	for (int i = 0; i < strLength; i++)   // 输入是否合法
		if ((str[i] > 'z' || str[i] < 'a')&& str[i] != ' ') return 1;
	return 0;
}

void encord()
{
   
	cout<<"  编  码  :"<< endl;
	double w = 0.0, len;
	areaBegin = 0.0, areaEnd = 1.0;

	//测试
	//cout << "rowLength: "<<rowLength << endl<<"num: "<<num<<endl;
	double proc[] = {
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };  // 概率初始化
	double proc_sum = 26;
	double probability[] = {
    1.0 / 26.0,1.0 / 26.0,1.0 / 26.0,1.0 / 26.0,1.0 / 26.0,
							1.0 / 26.0,1.0 / 26.0,1.0 / 26.0,1.0 / 26.0,1.0 / 26.0,
							1.0 / 26.0,1.0 / 26.0,1.0 / 26.0,1.0 / 26.0,1.0 / 26.0,
							1.0 / 26.0,1.0 / 
  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值