c++ 算术编码
程序员文章站
2022-07-14 22:19:36
...
/*
熵编码—算术编码
算术编码把整个信源序列表示为实数线上的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;
}
上一篇: 移动h5自适应布局直接拿去用
下一篇: ROS功能包