#include <iostream.h>
#include <cmath>
#define M 20 //定义符号序列的最大长度
#define N 2 //定义信源符号个数
class CalCode
{
public:
int length; //定义符号序列的实际长度
char n, sample[N]; //存放信源符号
double c, chance[N]; //存放信源符号的对应概率
char code[M]; //存放符号序列
double High, Low, high, low, data; //定义用于计算的各个变量
CalCode() //变量赋初值
{
High = 0;
Low = 0;
}
void Get_value(); //此函数用于提示输入信源相关值
void Get_code(); //此函数用于提示输入符号序列相关值
void coding(); //此函数用于具体的算术编码和结果输出
~CalCode(){} //析构函数,做清理工作
};
void CalCode::Get_value()
//此函数用于提示输入信源相关值
{
int i;
cout << "请输入" << N << "个信源符号:" << endl;
for(i = 0; i < N; i++)
{
cin >> n;
sample[i] = n;
}
cout << endl << "请输入" << N << "个信源符号对应的概率:" << endl;
for(i = 0; i < N; i++)
{
cin >> c;
chance[i] = c;
}
}
void CalCode::Get_code()
//此函数用于提示输入符号序列相关值
{
int i;
cout << endl << "请输入符号序列长: ";
cin >> length;
//判断输入的符号序列长度是否大于预定的值
while(length >= M)
{
cout << endl << "您输入的符号序列过长,请改小: ";
cin >> length;
}
cout << endl << "请输入要编码的符号序列: ";
for(i = 0; i < length; i++)
cin >> code[i];
}
void CalCode::coding()
//此函数用于具体的算术编码和结果输出
{
int i, k, l, c, j = 0, calcode[M];
double b, chance_l, Ps = 1;
for(i = 0; i < N; i++)
if(code[0] == sample[i])
break;
while(j < i)
Low += chance[j++];
data = chance[j];
High = Low + data;
for(i = 1; i < length; i++)
for(j = 0; j < N; j++)
{
if(code[i] == sample[j])
{
if(j == 0)
{
low = Low;
high = Low + chance[j] * data;
High = high;
data *= chance[j];
}
else
{
chance_l = 0.0;
for(k = 0; k <= j - 1; k++)
chance_l += chance[k];
low = Low + data * chance_l;
high = Low + data * (chance_l + chance[j]);
Low = low;
High = high;
data *= chance[j];
}
}
else continue;
}
//输出F(s)的计算结果
cout << endl << "经计算得到符号序列 ";
for(i = 0; i < length; i++)
cout << code[i];
cout << " 的F(s)为: " << Low << endl << endl;
//计算算术编码的码字长度l
for(i = 0; i < N; i++)
for(j = 0; j < length; j++)
if(sample[i] == code[j])
Ps *= chance[i];
l = int( ( log( 1.0 / Ps ) / log(2) ) + 0.999999 );
cout << "经计算得到算术编码的码字长度为: " << l << endl ;
//将F(s)转换为二进制,并存放于数组calcode中
for(i = 0; i < l; i++)
{
b = Low * 2;
c = int(b);
Low = b - c;
calcode[i] = c;
}
//解决有关算术编码的进位问题,给二进制数加1
if(calcode[l - 1] == 1)
{
for(i = l - 2; i >= 0;)
{
if(calcode[i] == 0)
{
calcode[i] = 1;
break;
}
else
{
calcode[i] = 0;
i--;
}
}
calcode[l - 1] = 0;
}
else calcode[l - 1] = 1;
//输出算术编码的结果
cout << endl << "将F(s)转换为算术编码的最终结果为: ";
for(i = 0; i < l; i++)
cout << calcode[i];
cout << endl << endl;
}
//主函数
int main()
{
CalCode a;
//各个函数的调用
a.Get_value();
a.Get_code();
a.coding();
return 0;
}