⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shannon.cpp

📁 //任意给定一个信源模型
💻 CPP
字号:
//任意给定一个信源模型,编程实现其二进制Shannon编码,输出编码结果并给出译码过程。

#include <iostream.h>
#include <stdlib.h>
#include <math.h>

//实现信源概率的输入,如果输入概率归一则返回1,否则返回0
 int Input(char X[],float P[],int num){
	int i=0;
	float Pa=0;       //累加概率以记录信源是否满足概率归一性
	cout<<"输入信源及对应概率:";	
	while(i<num){ 
		cin>>X[i];
		cin>>P[i];
		Pa=Pa+P[i];
		i++;
	}	
	if(Pa!=1)
	{	cout<<"     概率不归一,请确认后重新输入!!!"<<endl;
	    cout<<endl<<endl;
	    Input(X,P,num);
	    //exit(0);
	}
	 
	  return 1;
}

//对信源符号按概率按从大到小顺序排列
void Sort_P(char X[],float P[],float num)  
{  float temp,char Xtemp;
	for(int i=0;i<num;i++)
		for(int j=i+1;j<num+1;j++)       
				if(P[i]<P[j])
				{   
					temp=P[i];
					Xtemp=X[i];
					P[i]=P[j];
					X[i]=X[j];
					P[j]=temp;
			        X[j]=Xtemp;}
}

//实现第j个码字的累加概率
float Pacum(float P[],int j){   
	if(j==0)
		return 0;
	else 
		return (Pacum(P,j-1)+P[j-1]);
}

//计算每个信源的码长
int CodeLength(float P){
	return int(3.32*log10f(1/P)+1);
}

void Shannon(char X[],float P[],int num){  
	//CODER[10][20]用来存放香农码,p_dec为累加概率的小数部分  
	int k,CODER[10][20],j=0;   
	float p_dec;
	while(j<num){
		cout<<X[j]<<"  的编码是:";
		p_dec=Pacum(P,j)-int(Pacum(P,j));
		k=CodeLength(P[j]);
		for(int i=0;i<k;i++){
			CODER[j][i]=int(p_dec*2);
			cout<<CODER[j][i];
			p_dec=p_dec*2-int(p_dec*2);
		}
		j++;
		cout<<endl;
	}
}

//输入一个香农编码,实现译码功能
void Coding(char X[],float P[],int num){
	int i,k,m,CODER[10][20],j=0,n=-1;
	int code[10];  
	bool flag=false;    //flag用来标志译码是否成功
	cout<<"输入要译的编码:";
  while(code[n]!=2){   
		n++;
		cin>>code[n];
  }
  
	float p_dec;                  //将信源的编码存入一个二维数组中
	while(P[j]){
		p_dec=Pacum(P,j)-int(Pacum(P,j));
		k=CodeLength(P[j]);
		for(i=0;i<k;i++){
			CODER[j][i]=int(p_dec*2);
			p_dec=p_dec*2-int(p_dec*2);
		} 
		j++;
	}
 //此时的j是信源的个数
	i=0;	
	while(i<j&&!flag){
		m=0;
		flag=true;
		k=CodeLength(P[i]);
		if((n)==k)
		{   
			while(flag&&(m<k))
			{ 
				if(code[m]==CODER[i][m])
				{
					m++;
					flag=true;
				}
				else
					flag=false;
			}
		}
		else
			flag=false;
		i++;
	}
	if(flag)
		cout<<"对应的信源为:   "<<X[i-1]<<endl;
	else
		cout<<"没有信源与之对应"<<endl;
}


int main(){	
	int num,flag; //num是信源的个数,flag用来返回输入函数的值
	char X[20]={NULL};
    float P[10]={NULL};
	char ch,c,N,M;
	cout<<"                    WELCOME             "<<endl;
	cout<<"输入信源的个数:";
	cin>>num;	
	Input(X,P,num); 
	Sort_P(X,P,num);
	Shannon(X,P,num);
    cout<<"请根据需要选择!"<<endl;
	    cout<<"  ﹡﹡﹡﹡﹡﹡﹡ 1.编码请输入 S ﹡﹡﹡﹡﹡﹡﹡"<<endl;
		cout<<"  ﹡﹡﹡﹡﹡﹡﹡ 2.译码请输入 C﹡﹡﹡﹡﹡﹡﹡"<<endl;
		cout<<"  ﹡﹡﹡﹡﹡﹡﹡ 3.退出请输入 Q ﹡﹡﹡﹡﹡﹡﹡"<<endl;
		cout<<"请输入:";
		cin>>ch;
	switch(ch)
	{ case 'S':	 Shannon(X,P,num);break;
	  case 'C': do
				{Coding(X,P,num); 
				cout<<"是否还要译码?(Y/N)"<<endl;
				cin>>c;
				}
				while(c!='N');
				break;
	  case 'Q':  cout<<"成功退出!!"<<endl; break;
	  default:   cout<<"error"<<endl;
	}
    return 0;
}
		 

⌨️ 快捷键说明

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