信息论与编码实习报告.docx
《信息论与编码实习报告.docx》由会员分享,可在线阅读,更多相关《信息论与编码实习报告.docx(21页珍藏版)》请在冰豆网上搜索。
信息论与编码实习报告
信息论与编码实习报告
实验一唯一可译码判决准则
一、实验内容
编程实现唯一可译码的判决准则―――Sardinas-Patterson算法
二、实验环境
1.计算机
2.Windows2000或以上
3.VC++6.0
三、实验目的
1.进一步熟悉唯一可译码判决准则;
2.掌握VC开发环境的使用;
3.掌握C语言编程(尤其是字符串处理);
四、实验要求
1.提前预习实验,认真阅读实验原理。
2.认真高效的完成实验,实验过程中服从实验室管理人员以及实验指导老师的管理。
3.认真填写实验报告。
五、实验原理
1.唯一可译码判决准则的原理参考书1的153页。
其原理可简介如下:
将源码组C中所有可能的尾随后缀组成一个集合F,当且仅当集合F中没有包含任一码字,便可判断此码C为唯一可译变长码。
2.算法流程
输入码字集合X0
for所有Wi,Wj∈X0
if码字Wi是码字Wj的前缀,
即将相应的后缀作为一个尾随后缀放入新集合X1
endif
endfor
for所有Wi∈X0
for所有Wj∈Xn-1
ifWi是Wj的前缀,
即将相应的后缀作为一个尾随后缀放入新集合Xn中
elseifWj是Wi的前缀,
即将相应的后缀作为一个尾随后缀放入新集合Xn中
endif
endfor
endfor
构造尾随后缀集合X←Xi
if有码字Wi∈X0,Wi∈X,则非唯一可译码
6、实验设计
1、数据结构
本实验所需设计的程序中,码字可用如下结构表示:
charc[100][50]
尾随后缀用如下结构表示:
charf[300][50]
2、关键算法
本程序的关键算法是用来求尾随后缀的Sardinas-Patterson算法。
其算法流程图如下:
Y
N
Y
N
Y
N
N
Y
voidpatterson(charc[],chard[])//检测尾随后缀
{
inti,j,k;
for(i=0;;i++)
{
if(c[i]=='\0'&&d[i]=='\0')//2字符串一样,跳出
break;
if(c[i]=='\0')//d比c长,将d的尾随后缀放入f中
{
for(j=i;d[j]!
='\0';j++)f[sum][j-i]=d[j];
f[sum][j-i]='\0';
for(k=0;k{
if(strcmp(f[sum],f[k])==0)/*查看当前生成的尾随后缀在f集合中是否存在*/
{
sum--;break;
}
}
sum++;
break;
}
if(d[i]=='\0')//c比d长,将c的尾随后缀放入f中
{
for(j=i;c[j]!
='\0';j++)f[sum][j-i]=c[j];
f[sum][j-i]='\0';
for(k=0;k{
if(strcmp(f[sum],f[k])==0)/*查看当前生成的尾随后缀在f集合中是否存在*/
{
sum--;break;
}
}
sum++;
break;
}
if(c[i]!
=d[i])//字符不一样了也退出
break;
}
}
3、函数调用关系图
Main()函数调用voidpatterson(charc[],chard[])函数。
8、用户手册及总结
用户手册:
1.按照提示先输入随后将输入字符串的总个数
2.依次输入个字符串
3.得出结果
总结:
本次编程实验中进一步加深了对尾随后缀集合算法的理解,运用C语言将其实现。
在程序中设置了一个互相比较两个字符串是否为对方前缀的函数,以求得尾随后缀。
程序大体写完后,又在原程序的基础上增加了它的鲁棒性。
附源代码:
#include
#include
charc[100][50];
charf[300][50];
intN,sum=0;//N为输入码字的个数,sum为尾随后缀集合中码字的个数
intflag;//判断是否唯一可译标志位
voidpatterson(charc[],chard[])//检测尾随后缀
{
inti,j,k;
for(i=0;;i++)
{
if(c[i]=='\0'&&d[i]=='\0')//2字符串一样,跳出
break;
if(c[i]=='\0')//d比c长,将d的尾随后缀放入f中
{
for(j=i;d[j]!
='\0';j++)f[sum][j-i]=d[j];
f[sum][j-i]='\0';
for(k=0;k{
if(strcmp(f[sum],f[k])==0)/*查看当前生成的尾随后缀在f集合中是否存在*/
{
sum--;break;
}
}
sum++;
break;
}
if(d[i]=='\0')//c比d长,将c的尾随后缀放入f中
{
for(j=i;c[j]!
='\0';j++)f[sum][j-i]=c[j];
f[sum][j-i]='\0';
for(k=0;k{
if(strcmp(f[sum],f[k])==0)/*查看当前生成的尾随后缀在f集合中是否存在*/
{
sum--;break;
}
}
sum++;
break;
}
if(c[i]!
=d[i])//字符不一样了也退出
break;
}
}
/*主函数*/
main()
{
inti,j;
printf("请输入码字的个数(小于100):
");//输入码得个数
scanf("%d",&N);
while(N>100)
{
printf("输入码字个数过大,请输入小于100的数\n");
printf("请输入码字的个数(小于100):
");
scanf("%d",&N);
}
flag=0;
printf("请分别输入码字(每个码字长度小于50个字符):
\n");
for(i=0;i{
scanf("%s",&c[i]);
}
for(i=0;ifor(j=i+1;j{
if(strcmp(c[i],c[j])==0)
{flag=1;break;}
}
if(flag==1)//如果码本身有重复,就可以断定它不是唯一可译码
{
printf("这不是唯一可译码。
\n");
}
else
{
for(i=0;i{
for(j=i+1;j{
patterson(c[i],c[j]);
}
}
for(i=0;;i++)//根据原始码与s[i]生成s[i+1]也放入f[i]
{
ints=0;
for(j=0;j{
if(i==sum)
{s=1;break;}
else
patterson(f[i],c[j]);
}
if(s==1)break;
}
for(i=0;i{
for(j=0;j{
if(strcmp(f[i],c[j])==0)
{
flag=1;
break;
}
}
}
if(flag==1)
{
printf("这不是唯一可译码。
\n");
}
else
printf("这是唯一可译码。
\n");
}
printf("尾随后缀集合为:
");
for(i=0;i<=sum;i++)
printf("\n%s",f[i]);
}
实验二Shannon编码
一、实验内容
编程实现Shannon编码算法
二、实验环境
1.计算机
2.Windows2000或以上
3.VC++6.0
三、实验目的
1.进一步熟悉Shannon编码算法;
2.掌握C语言编程(尤其是数值的进制转换,数值与字符串之间的转换等)
四、实验要求
1.提前预习实验,认真阅读实验原理。
2.认真高效的完成实验,实验过程中服从实验室管理人员以及实验指导老师的管理。
3.认真填写实验报告。
五、实验原理
1.Shannon编码的原理参考书1的162页。
2.算法流程
输入信源符号个数q,信源概率分布P
降序排列{pi}
fori=1→q
计算编码长度
;
计算累加概率
;
将累加概率F(si)(十进制小数)变成二进制数
取小数点后li位数作为第i个消息的码字。
endfor
六、参考书
1.《信息论——基础理论及应用》傅祖芸,电子工业出版社
七、实验设计
1、数据结构
本实验所需设计的程序中,码字可用如下结构表示:
typedefstructsymbol
{
chars[50];
doublepa,pb,h;//分别为符号概率,累加概率,自信息量
intl;//码字长度
charm[100];//码字
}symbol;
2、关键算法
本程序的关键算法是通过累加概率及码长求码字,其算法流程图如下:
Y
N
N
Y
for(i=0;i{
p=sb[i].pb;
for(j=0;j{
p=p*2;
if(p>=1)
{
sb[i].m[j]='1';
p=p-1;
}
elsesb[i].m[j]='0';
}
sb[i].m[sb[i].l]='\0';
}
3、函数调用关系图
仅有main()函数。
概率排序、求累加概率、自信息量、码字长度、码字的函数均包含在main()函数内。
9、用户手册及总结
用户手册:
1.按照提示先输入信源的总个数
2.依次输入各信源的名称
3.再按上序输入信源的概率
4.得出结果
总结:
本次编程中没有用到特别复杂的算法。
按照香农编码的编码方法依次实现各模块即可。
在编程中要注意的是数字的类型,利用log函数时求得的值是double型。
附源代码:
#include
#include
#include
typedefstructsymbol
{
chars[50];
doublepa,pb,h;//分别为符号概率,累加概率,自信息量
intl;//码字长度
charm[100];//码字
}symbol;
intN;
voidmain()
{
inti,j;
symbolsb[100];
printf("请输入符号的个数:
");
scanf("%d",&N);
printf("请依次输入消息符号:
\n");
for(i=0;i{
scanf("%s",sb[i].s);
}
printf("请依次输入各消息符号的概率:
\n");
for(i=0;i{
scanf("%lf",&sb[i].pa);
}
intx;
symbolz;
for(i=0;i{
x=i;
for(j=i+1;j{
if(sb[x].pa}
z=sb[i];sb[i]=sb[x];sb[x]=z;
}
sb[0].pb=0;
for(i=1;i{
sb[i].pb=sb[i-1].pb+sb[i-1].pa;
}
doubley;
for(i=0;i{
sb[i].h=-log(sb[i].pa)/log
(2);
y=sb[i].h;
if(sb[i].h-(int)y==0)sb[i].l=(int)y;
elsesb[i].l=(int)(y+1);
}
doublep;
for(i=0;i{
p=sb[i].pb;
for(j=0;j{
p=p*2;
if(p>=1)
{
sb[i].m[j]='1';
p=p-1;
}
elsesb[i].m[j]='0';
}
sb[i].m[sb[i].l]='\0';
}
printf("消息符号符号概率累加概率信息量码字长度码字\n");
for(i=0;iprintf("%-8s%1.4lf%1.4lf%1.4lf%3d%s\n",sb[i].s,sb[i].pa,sb[i].pb,sb[i].h,sb[i].l,sb[i].m);
}