基本思想
用0到1之间的一个数值区间来表示字符,而不是为每一个需要编码的字符分配一个单独的编码(如霍夫曼编码)。输出时可以从该区间内选择出任意一个小数作为实际编码。
编码例题及程序
某字符序列含有a,b,c,d,e五个字符,输入为各个字符的出现概率,及需要编码的字符序列,输出为算术编码区间(保留小数点后10位)。
样例输入:
0.2 0.3 0.1 0.15 0.25
aaabded
样例输出:
0.0033640000
0.0033775000
程序代码:
// 程序名称:算术编码的区间输出
#include<iostream>
#include<iomanip>
using namespace std;
int main(void)
{
//数据定义部分
double p[5];
string origin_code;
double cumsum_p[5] = { 0 };
unsigned j(0);
//数据输入部分
for (unsigned i(0); i < 5; ++i)
{
cin >> p[i];
}
cin >> origin_code;
//数据处理部分
for (unsigned i(1); i < 5; ++i)
{
cumsum_p[i] = cumsum_p[i - 1] + p[i - 1];
}
unsigned slength = origin_code.length();
double leftPole(0), rightPole(1);
double RangeLength, tempLeft, tempRight;
for (unsigned i(0); i < slength; ++i)
{
RangeLength = rightPole - leftPole;
switch (origin_code[i])
{
case'a': {tempLeft = leftPole; tempRight = leftPole + cumsum_p[1] * RangeLength; break; }
case'b': {tempLeft = leftPole + cumsum_p[1] * RangeLength; tempRight = leftPole + cumsum_p[2] * RangeLength; break; }
case'c': {tempLeft = leftPole + cumsum_p[2] * RangeLength; tempRight = leftPole + cumsum_p[3] * RangeLength; break; }
case'd': {tempLeft = leftPole + cumsum_p[3] * RangeLength; tempRight = leftPole + cumsum_p[4] * RangeLength; break; }
case'e': {tempLeft = leftPole + cumsum_p[4] * RangeLength; tempRight = rightPole; break; }
}
leftPole = tempLeft;
rightPole = tempRight;
}
//结果输出部分
cout << fixed << setprecision(10) << leftPole << endl << fixed << setprecision(10) << rightPole ;
return 0;
}
译码例题及程序
对于由a,b,c,d,e 5个符号组成的符号序列,输入各符号的出现概率及其算术编码,输出译码后的符号,符号长度是10位。
样例输入:
0.2 0.3 0.1 0.15 0.25
0.0033713425
样例输出:
aaabdedcbc
程序代码:
//程序名称:算术编码译码程序
#include<iostream>
using namespace std;
int main(void)
{
//数据定义部分
double p[5];
double code;
double leftPoles[5];
double rightPoles[5];
string code_elements = "abcde";
string Translate_code;
unsigned time(0);
//数据输入部分
for (unsigned i=0; i < 5; ++i)
{
cin >> p[i];
}
cin >> code;
//数据处理部分
for (unsigned j=0; j < 5; ++j)
{
if (j == 0)
{
leftPoles[j] = 0;
rightPoles[j] = p[0];
}
else if (j == 4)
{
leftPoles[j] = 1 - p[4];
rightPoles[j] = 1;
}
else
{
leftPoles[j] = leftPoles[j - 1] + p[j - 1];
rightPoles[j] = rightPoles[j - 1] + p[j];
}
}
while (code != 1&&time++<10)
{
for (unsigned k(0); k < 5; ++k)
{
if (leftPoles[k] <= code && code < rightPoles[k])
{
Translate_code += code_elements[k];
code = (code - leftPoles[k]) / (rightPoles[k] - leftPoles[k]);
break;
}
}
}
//结果输出部分
cout << Translate_code << endl;
return 0;
}