欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

c++ 算术编码

程序员文章站 2022-07-14 22:19:36
...

c++ 算术编码
c++ 算术编码

/*
	熵编码—算术编码

	算术编码把整个信源序列表示为实数线上的0到1之间的一个区间,其长度等于该序列的概率,在该区间内选择一个代表性的小数(最少位数),转化为二进制作为实际的编码输出。
	序列中的每个新增元素都要用来缩短这个区间。消息序列中元素越多,所得到的区间就越小,区间越小,就需要更多的数位来表示这个区间。
	采用算术编码每个符号的平均编码长度可以为小数。
*/

/*
	00  概率: 0.1  区间 [0,0.1)
	01  概率: 0.4  区间 [0.1,0.5)
	10  概率: 0.2  区间 [0.5,0.7)
	11  概率: 0.3  区间 [0.7,1)
*/

#include<iostream>
#include<iomanip>
using namespace std;

//声明编码的长度
int length = 0;
double Code()
{
	int input;
	double left = 0, right = 1, start;
	cout << "请输入两位的二进制编码,以空格分隔,以换行结束:" << endl;
	while (cin >> input)
	{
		//记下编码的长度作为解码的精度
		++length;
		//判断输入的字符
		switch (input)
		{
		//输入00则把区间缩减为原区间的0%到10%部分
		case 00:
			right = left + (right - left) * 0.1;
			break;
		//输入01则把区间缩减为原区间的10%到50%部分
		case 01:
			start = left;
			left = start + (right - start) * 0.1;
			right = start + (right - start) * 0.5;
			break;
		//输入10则把区间缩减为原区间的50%到70%部分
		case 10:

			start = left;
			left = start + (right - start) * 0.5;
			right = start + (right - start) * 0.7;
			break;
		//输入11则把区间缩减为原区间的70%到100%部分
		case 11:
			left = left + (right - left) * 0.7;
			break;
		//输入错误,不予处理
		default:
			cout <<endl<< "输入错误!" << endl<<endl;
			break;
		}
		//中间结果输出
		//cout << fixed << setprecision(15) << endl << left << endl;
		if (cin.get() == '\n')
			break;
	}
	cout << endl << "编码结果:";
	cout << setprecision(15) << endl << left << endl;
	return left;
}
void Decode(double code)
{
	cout << endl << "解码结果:" << endl;
	double left = 0, right = 1;

	//解码精度为编码的长度
	for (int i = 0; i < length; ++i)
	{
		//声明dis为区间范围
		double dis = right - left;

		//如果要解码的数在当前区间dis的0%到10%部分,则输出解码值00,并缩小区间为原区间的0%到10%部分
		if (code < left + dis * 0.1)
		{
			cout << "00 ";
			right = left + dis * 0.1;
		}
		//如果要解码的数在当前区间dis的10%到50%部分,则输出解码值01,并缩小区间为原区间的10%到50%部分
		else if (code < left + dis * 0.5)
		{
			cout << "01 ";
			double start = left;
			left = start + dis * 0.1;
			right = start + dis * 0.5;
		}
		//如果要解码的数在当前区间dis的50%到70%部分,则输出解码值10,并缩小区间为原区间的50%到70%部分
		else if (code < left + dis * 0.7)
		{
			cout << "10 ";
			double start = left;
			left = start + dis * 0.5;
			right = start + dis * 0.7;
		}
		//如果要解码的数在当前区间dis的70%到100%部分,则输出解码值11,并缩小区间为原区间的70%到100%部分
		else
		{
			cout << "11 ";
			left = left + dis * 0.7;
		}
	}

}
int main()
{
	//编码
	double code = Code();
	
	//解码
	Decode(code);

	return 0;
}
相关标签: 课程大作业 c++