算术编码的C实现.docx
- 文档编号:30764114
- 上传时间:2023-08-23
- 格式:DOCX
- 页数:9
- 大小:22.72KB
算术编码的C实现.docx
《算术编码的C实现.docx》由会员分享,可在线阅读,更多相关《算术编码的C实现.docx(9页珍藏版)》请在冰豆网上搜索。
算术编码的C实现
文件管理序列号:
[K8UY-K9IO69-O6M243-OL889-F88688]
算术编码的C实现
算术编码的C++实现
#include
#include
#include
#include
usingnamespacestd;
#defineN50//输入的字符应该不超过50个
structL//结构用于求各字符及其概率
{
charch;//存储出现的字符(不重复)
intnum;//存储字符出现的次数
doublef;//存储字符的概率
};
//显示信息
voiddisp();
//求概率函数,输入:
字符串;输出:
字符数组、字符的概率数组;返回:
数组长度;
intproba(stringstr,charc[],longdoublep[],intcount);
//求概率的辅助函数
intsearch(vector
//编码函数,输入:
字符串,字符数组,概率数组,以及数组长度;输出:
编码结果
longdoublebma(charc[],longdoublep[],stringstr,intnumber,intsize);
//译码函数,输入:
编码结果,字符串,字符数组,概率数组,以及它们的长度;输出:
字符串
//该函数可以用于检测编码是否正确
voidyma(stringstr,charc[],longdoublep[],intnumber,intsize,longdoubleinput);
intmain()
{
stringstr;//输入要编码的String类型字符串
intnumber=0,size=0;//number--字符串中不重复的字符个数;size--字符串长度
charc[N];//用于存储不重复的字符
longdoublep[N],output;//p[N]--不重复字符的概率,output--编码结果
disp();
cout<<"输入要编码的字符串:
";
getline(cin,str);//输入要编码的字符串
size=str.length();//字符串长度
number=proba(str,c,p,size);//调用求概率函数,返回不重复字符的个数
cout.setf(ios:
:
fixed);//“魔法配方”规定了小数部分的个数
cout.setf(ios:
:
showpoint);//在此规定编码结果的小数部分有十个
cout.precision(10);
output=bma(c,p,str,number,size);//调用编码函数,返回编码结果
yma(str,c,p,number,size,output);//调用译码函数,输出要编码的字符串,
//以验证编码是否正确
return0;
}
//显示信息
voiddisp()
{
cout< cout<<"********************算术编码*********************\n"; cout<<"*****************作者: heiness******************\n"; cout< cout<<"此程序只需要输入要编码的字符串,不需要输入字符概率\n"; cout< } //求概率函数 intproba(stringstr,charc[],longdoublep[],intcount) { cout.setf(ios: : fixed);//“魔法配方”规定了小数部分位数为三位 cout.setf(ios: : showpoint); cout.precision(3); vector Ltemp;//结构类型的变量 temp.ch=str[0];//暂存字符串的第一个字符,它的个数暂设为1 temp.num=1; temp.f=0.0; pt.push_back(temp);//将该字符及其个数压入向量 for(inti=1;i { temp.ch=str[i];//暂存第二个字符 temp.num=1; temp.f=0.0; for(intj=0;j {//若重复,该字符个数加1,并跳出循环 intk;//若不重复,则压入该字符,并跳出循环 k=search(pt,str[i],pt.size()); if(k>=0) { pt[k].num++; break; } else { pt.push_back(temp); break; } } } for(i=0;i { pt[i].f=double(pt[i].num)/count; } intnumber=pt.size();//计算不重复字符出现的次数 cout<<"各字符概率如下: \n"; for(i=0;i { if(count==0) { cout<<"NOsample! \n"; } else { c[i]=pt[i].ch; p[i]=pt[i].f; cout< "< } } returnnumber;//返回不重复字符的个数 } //求概率的辅助函数 //若搜索发现有重复字符返回正数 //否则,返回-1 intsearch(vector { for(inti=0;i if(ch1==arch[i].ch)returni; return-1; } //编码函数 longdoublebma(charc[],longdoublep[],stringstr,intnumber,intsize) { longdoubleHigh=0.0,Low=0.0,high,low,range; //High--下一个编码区间的上限,Low--下一个编码区间的下限; //high--中间变量,用来计算下一个编码区间的上限; //low--中间变量,用来计算下一个编码区间的下限; //range--上一个被编码区间长度 inti,j=0; for(i=0;i if(str[0]==c[i])break;//编码第一个字符 while(j Low+=p[j++];//寻找该字符的概率区间下限 range=p[j];//得到该字符的概率长度 High=Low+range;//得到该字符概率区间上限 for(i=1;i for(j=0;j { if(str[i]==c[j]) { if(j==0)//若该字符在c数组中的第一个字符 { low=Low;//此时该字符的概率区间下限刚好为零 high=Low+p[j]*range; High=high; range*=p[j];//求出该字符的编码区间长度 } else//若该编码字符不是c数组中的第一个 { floatproba_next=0.0; for(intk=0;k<=j-1;k++) proba_next+=p[k];//再次寻找字符的概率区间下限 low=Low+range*proba_next;//编码区间下限 high=Low+range*(proba_next+p[j]);//编码区间上限 Low=low;//编码区间下限 High=high;//编码区间上限 range*=p[j];//编码区间长度 } } elsecontinue;//i++,编码下一个字符 } cout< cout<<"输入字符串的编码为: "< returnLow; } //译码函数 voidyma(stringstr,charc[],longdoublep[],intnumber,intsize,longdoubleinput) { vector longdoubletemp;//中间变量 longdoublesum[N];//存储不重复字符概率区间的下限 sum[0]=0.0;//数组第一个元素为0 for(inti=1;i { sum[i]=sum[i-1]+p[i-1]; } for(intj=0;j { for(intk=0;k {//确定被编码字符的下限属于【0,1】之间的哪一段 if((input>sum[k])&&(input { v.push_back(str[j]); temp=(input-sum[k])/(sum[k+1]-sum[k]);//计算下一个被编码字符的下限 input=temp; break; } else continue; } } cout< cout<<"译码输出为: ";//将译码结果输出 for(intm=0;m { cout< } cout< }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算术 编码 实现