信息与编码实验教案Word格式文档下载.docx
《信息与编码实验教案Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《信息与编码实验教案Word格式文档下载.docx(14页珍藏版)》请在冰豆网上搜索。
O
0.0654
L
0.029
V
0.008
A
0.063
C
0.023
K
0.003
N
0.059
F,U
0.0225
X
0.002
I
0.055
M
0.021
J,Q,Z
0.001
R
0.054
P
0.0175
实验内容:
1.将一大段英文文章作为要统计的样本文件
2.对样本文件进行一维概率统计,并计算出信源熵及冗余度
3.对样本文件进行二维概率统计,并计算出信源熵及冗余度
在进行统计时,首先要在程序中打开文件,然后对文件中的字符读入程序中,进行统计。
而
在二维统计时,尤其要求对文件的指针操作要熟悉。
如读入“newspaper”时,应该依次读入“neewwssppaappeer”,而如果使用fgetc()等命令读文件时,读入的是“newspape”为了依次读入“neewwssppaappeer”,就要求在每次调入fgetc()等命令后,再将文件指针往后退一步,即要求学生能熟练使用fseek()命令进行指针定位操作。
二维信源熵程序如下:
#include<
stdio.h>
math.h>
stdlib.h>
#defineNULL0
intcharge(charc)
{intn;
if(c>
=65&
&
c<
=90)
c=c+32;
if(c>
+97&
=122)
{n=c-97;
returnn;
}
elsereturn-1;
}
voidmain()
{intcount[26][26]={0};
charzifu1,zifu2;
inti,n,m,j;
intsum=0;
floatq,sum1=0;
FILE*fp;
If((fp=fopen(“file”,“rb”))==NULL)
{printf(“can’topenfile!
\n”);
exit(0);
while(!
feof(fp))
{zifu1=fgetc(fp);
n=charge(zifu1);
if(n!
=-1)
{zifu2=fgetc(fp);
m=charge(zifu2);
if(m!
{count[n][m]++;
fseek(fp,-1,1);
fclose(fp);
for(i=0;
i<
26;
i++)
for(j=0;
j<
j++)
sum=sum+count[i][j];
printf(“thenumberofallthecodeis%d\n”,sum);
q=(float)sum;
{if(j%3==0)printf(“\n”);
printf(“%c%c,%4d,%6.5f%%”,i+97,j+97,count[i][j],count[i][j]*100/q);
printf(“\n”);
if(count[i][j])
sum1=sum1+(float)((count[i][j]/q)*log10(1/(double)(count[i][j]/q))/log10((double)
(2)));
printf(“\n信息熵为:
H(x)=%f\n”,sum1);
实验要求:
1)自己生成一个英文文件,可以在网上找,也可以自己生成。
为了保证实验数据的可靠性,数据的量要比较大。
为了保证二维信源统计的可靠性,建议文件的英文字符在十万以上。
2)编写一维信源统计程序,得出一维统计频次,计算信源熵及剩余度。
3)编写二维信源统计程序,得出二维统计频次,计算信源熵及剩余度。
4)提交二维信源剩余度的实验报告,及实验体会心得。
实验二、香农编码
Hfffman编码、Fano编码以及Shannon编码是重要的统计编码形式,在信源编码中具有重要的作用。
由于Huffman编码在数据结构课程中已经出现。
因此,选用Shannon编码为主要练习对象。
Shannon码编码步骤为:
1.将信源
的所有符号按概率从大到小排列:
2.对第
个信源符号
取整数码长
为取整运算
3.计算累加概率
4.将
变换成二进制数
,并按步骤2中计算的长度
取
的二进制系数
,组合起来即为
的香农码字
.
程序如下:
#include<
iostream.h>
doubleP[6]={0.25,0.1,0.2,0.25,0.15,0.05},Pax[6],machang[6];
{doubletemp;
for(inta=1;
a<
6;
a++)
{
for(inti=0;
6-a;
if(P[i]<
P[i+1])
{
temp=P[i];
P[i]=P[i+1];
P[i+1]=temp;
}
cout<
<
P[i]<
"
"
;
endl;
Pax[0]=0.0;
Pax[i+1]=Pax[i]+P[i];
概率累加和为:
cout<
Pax[i]<
for(i=0;
doublem=log(1/P[i])/log
(2);
if(m-int(m)==0)
machang[i]=log(1/P[i])/log
(2);
else
machang[i]=int(m)+1;
cout<
的码长为:
machang[i]<
for(intj=0;
machang[i];
{
intn=int(Pax[i]*2);
n;
if((Pax[i]*2-1)>
0)
{
Pax[i]=Pax[i]*2-1;
continue;
}
if((Pax[i]*2-1)==0)
Pax[i]=Pax[i]*2-1;
Pax[i]=Pax[i]*2;
}
1)熟练掌握香农编码的原理
2)掌握二进制小数的输出方法
3)如果时间允许,建议完成Huffman编码的程序设计。
4)完成香农编码的实验报告及实验心得体会。
实验三、循环码
循环码是线性分组码的一种,具有较好的数学特征,可以用代数理论对循环码进行研究。
在循环码的编码与校验过程中,
上多项式的除法是重要环节。
在徐士良的《常用算法程序集(C语言描述)》中,有实系数的多项式除法。
对其进行改进,使其系数定义在
上,可很好地实现循环编码及校验的要求。
完成二进制多项式除法的设计,程序中
其中
在循环码中,只需保留多项式相除的余式
即可。
下面的程序中,
,
,最后余式
#include"
stdio.h"
jiajian(a,b)
inta,b;
{if(a==1&
b==1)return(0);
if(a==0&
b==1)return
(1);
if(a==1&
b==0)return
(1);
b==0)return(0);
cheng(a,b)
chu(a,b)
{if(a==1&
if(a==0)return(0);
voidpdiv(p,m,q,n,s,k,r,l)
intm,n,k,l,p[],q[],s[],r[];
{inti,j,mm,ll,kk;
i<
=k-1;
i++)s[i]=0;
ll=m-1;
for(i=k;
i>
=1;
i--)
{s[i-1]=chu(p[ll],q[n-1]);
mm=ll;
for(j=1;
j<
j++)
{kk=cheng(s[i-1],q[n-j-1]);
p[mm-1]=jiajian(p[mm-1],kk);
mm=mm-1;
ll=ll-1;
for(i=0;
=l-1;
i++)
{r[i]=p[i];
printf("
%d"
r[i]);
return;
main()
{inti;
staticintp[6]={1,1,0,0,0,1};
staticintq[4]={1,1,0,1};
ints[3],r[3];
pdiv(p,6,q,4,s,3,r,3);
1)熟练掌握CRC编码的原理
2)领会二进制除法在CRC编码中的作用
3)完成
上多项式的除法的程序设计
4)鼓励学生在以上程序的基础上,完成CRC编码、CRC译码的程序设计
5)提交
上多项式的除法的实验报告、实验心得体会
实验四、有限域上插值多项式的构造
依据
个点
构造
次插值多项式
,实质上是求解
无非线性方程组,当插值点数不是很多的时候,可以在较短的时间内计算出插值多项式
的系数
,使之满足
但通常的实数域上的计算,无法解决误差问题,为了避免误差问题,我们将插值多项式定义在有限域上,构造出无误差的插值多项式。
当
为素数时,
为有限域,记
为有限域
上的多项式。
例如:
设
满足
的插值多项式
即求解方程组
得
解有限域上范德蒙方程组算法思想:
Step0输入向量组
素数p.
Step1对k=1,2,
n-1,执行
(i)对
执行
;
对
执行
(ii)如果abs(y[i])>
p,y[i]%=p;
如果y[i]<
0;
y[i]+=p;
(确保运算的对象范围均在(0,p)上)
(iii)对
Step2对k=1,2,
(i)
Step3输出范德蒙方程组的解x=b.
///////////////////////////////////////////////////////////////////////////////////////////////////
//看程序之前,请仔细阅读解有限域上范德蒙方程组算法思想,如上
//运算过程确保每一步运算的数均在(0,p)内.
malloc.h"
stdlib.h"
intprime=7;
//全局变量,确定上限素数
voidVandermond(intn,int*x,int*y);
//函数解范德蒙方程组,解即为所要求的系数
intInverse(intxx);
//求逆元
voidmain()//主函数入口
{
intn=3;
intx[3]={1,2,4};
inty[3]={2,6,5};
Vandermond(n,x,y);
//调用函数求解系数,并存入数组y中
voidVandermond(intn,int*x,int*y)//解范德蒙方程组,以获取系数,并存入原数组y中
{intyy,xx;
//定义中间变量,以确保每一步运算中间产生的数均在(0,p)范围内.
inttemp;
//
for(intk=0;
k<
n-1;
++k)
for(inti=n-1;
i>
k;
--i)
{yy=y[i]-y[i-1];
xx=x[i]-x[i-k-1];
if(yy%xx==0)
y[i]=yy/xx;
//判断xx是否整除yy,否则取yy乘以其逆元
if(y[i]<
0){y[i]%=prime;
y[i]+=prime;
else
y[i]=yy*Inverse(xx);
if(y[i]>
prime)y[i]%=prime;
elseif(y[i]<
0){y[i]%=prime;
y[i]+=prime;
for(k=n-2;
k>
=0;
--k)
for(inti=k;
++i)
{
temp=y[i+1]*x[k];
if(temp>
prime)temp%=prime;
if(temp<
0){temp%=prime;
temp+=prime;
y[i]-=temp;
if(y[i]>
if(y[i]<
y[i]+=prime;
解为:
);
++i)printf("
%d\t"
y[i]);
//输出系数
//求x的逆元
//令i=1,2...p,如果满足x*i%p==1,i即为x的逆元
intInverse(intxx)//求xx逆元
if(xx<
0){xx%=prime;
xx+=prime;
for(inti=1;
prime;
i++)
temp=xx*i;
if(temp%prime==1)returni;
return0;
1)理解有限域的概念及有限域上的四则运算
2)用程序实现有限域上的方程组的解法。
3)完成实验报告及实验心得体会。