内容与设计思想
首先建立信源的数据存储类class DATA,按照教材方式建立数据成员变量.设有离散无记忆信源X,P(X).二进制香农编码为:1.将信源符号按概率从大到小的顺序排列2.令P(X0)=0,用P(Xj)表前面概率的累加概率,最后该信源的码字将用此值表示3.令Ki为第I个码字的长度,确定整数Ki满足不等式:-log2 P(Xi)<=Ki<1- log2 P(Xi).4.将P(Xj)用二进制表示,并取小数点后Ki位作为符号X的编码.
在信源输入时完成对信源中P(Xi) P(Xj) Ki的计算,然后把信源数据赋给算码字的函数a进行码字计算.码字计算完毕后会将结果返回给输入信源中的key元素,每个信源即得到自己的香农编码
香农编码比较定长编码有更高的效率,因为它对信源进行了压缩.
#include "iostream.h"
#include "math.h"
class DATA//数据类
...{
public:
DATA()...{next=NULL;qian=NULL;}
char Xi;
char* key;
float PXi,PXj;
int Ki;
DATA *next,*qian;
};
void a(DATA *p)//算码字
...{
int l=0,y=p->Ki;
char* L=new char[y];
float z=p->PXj;
while(y>0)
...{
z=z*2;
if(z>=1)//->字符0.1
...{z=z-1;
L[l]='1';}
else L[l]='0';
l++;
y--;
}//此时得到编码数组L
p->key=L;//赋给信源数组
}
void main()
...{int l;
float z,y=0;
char L;
DATA *p=new DATA;//ini
DATA *head=p;//ini
while(1)
...{cout<<"1.编码"<<endl<<"2.结束程序"<<endl;
cin>>l;
if(l>=2) break;
switch(l)//选择
...{
case 1:...{//输入信源排序并编码
cout<<"分别输入Xi与PXi的值,PXi的值输入9表示输入结束"<<endl;
while(1)
...{
cout<<"Xi的值:";
cin>>L;
cout<<"PXi的值:";
cin>>z;
if(z==9) break;
p->Xi=L;//赋值
p->PXi=z;
if(p->qian==NULL) p->PXj=0;
else ...{p->PXj=p->qian->PXi+p->qian->PXj;}//!
p->Ki=int(0.999-log10(z)/log10(2));
p->next=new DATA;
p->next->qian=p;
p=p->next;
}//到此完成对信源的输入及初始计算
for(p=head;p->next!=NULL;p=p->next)
...{
a(p);
cout<<p->key;//输出编码
}
cout<<endl;
break;
}
}
}
}

1777

被折叠的 条评论
为什么被折叠?



