📄 shannon.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 + -