算术编码.cpp

来自「算术编码熵编码Arithmetic Coding」· C++ 代码 · 共 105 行

CPP
105
字号
#include<iostream>
#include<vector>
#include<iomanip>
#include<cmath>
using namespace std;
typedef vector<int> vt;
void main(){
 vt a,b,c;
 int x,i,j,k; 
 double low,high,mid,t1=1.0;  
 double v[100][11];//存储个节点对应坐标。。。
 cout<<"请输入待编码的字符串:";
 cin>>x;
 a.push_back(x%10);
 while(x/10!=0){
  a.push_back((x/10)%10);
  x=x/10;
 }
 for(i=1;i<=a.size();i++){
  b.push_back(a[a.size()-i]);
 }//b[i]为字符
 double p[100][10];
 double s[100][10];
 for(i=0;i<=b.size();i++){
  for(j=0;j<10;j++){
   s[i][j]=1;
  }
 }
 for(i=0;i<=b.size();i++){
  for(j=0;j<10;j++){
   if(b[i]==j){    
     s[i+1][j]=s[i][j]+1;
     for(k=i+1;k<b.size();k++)
      s[k+1][j]=s[k][j];
   }
  }
 }
 for(i=0;i<=b.size();i++){
  for(j=0;j<10;j++){
   cout<<s[i][j];
  }
  cout<<endl;
 }
 for(i=0;i<=b.size();i++){
  for(j=0;j<10;j++){
   p[i][j]=s[i][j]/(10+i);
  }
 }
 for(i=0;i<=b.size();i++){
  cout<<"加入第"<<i<<"个元素自适应概率为:"<<endl;
  for(j=0;j<10;j++){  
   cout<<setprecision(5)<<p[i][j]<<" ";
  }
  cout<<endl;
 }
 for(i=0;i<=b.size();i++){
  for(j=0;j<10;j++){
   v[i][0]=0;v[i][10]=1;
   v[i][j+1]=v[i][j]+p[i][j];
  }
 }  
 cout<<'\n'<<endl;
  for(i=0;i<=b.size();i++){
  cout<<"加入第"<<i<<"个元素后对应坐标为:"<<endl;
  for(j=0;j<=10;j++){  
   cout<<setprecision(5)<<v[i][j]<<" ";
  }
  cout<<endl;
 }
  cout<<'\n'<<endl;
  for(i=0;i<b.size();i++){     
    t1=t1*p[i][b[i]];  
 }
 //const int length=(int)(-log(t1)/log(2))+1;
 //cout<<"所需码长为:"<<length<<endl;
 //////////////////////////////////////////////////////////////////
 /////////////////////////以下为编码部分///////////////////////////
 //////////////////////////////////////////////////////////////////
 low=v[0][b[0]];high=v[0][b[0]+1];
 for(i=1;i<b.size();i++){  
   low=low+(high-low)*v[i][b[i]];
   double temp=(low-v[i][b[i]]*high)/(1-v[i][b[i]]);
   high=temp+(high-temp)*v[i][b[i]+1]; 
 }
 mid=(high+low)/2;
  double result=mid;
  const int length=-log(high-low)/log(2)+1;
  cout<<"所需码长为:"<<length<<endl;
 cout<<setprecision(10)<<low<<'\t'<<high<<'\t'<<mid<<endl;  
 for(i=0;i<length;i++){//转换成二进制
   mid=mid*2;
  if(mid<1){
   c.push_back(0);
   }
  else{
    c.push_back((int)mid);
    mid-=1;
   }
  }
  cout<<"编码结果如下:"<<endl;
  for(i=0;i<c.size();i++)
   cout<<c[i]; 
  cout<<endl; 
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?