信息论实验报告.docx
《信息论实验报告.docx》由会员分享,可在线阅读,更多相关《信息论实验报告.docx(15页珍藏版)》请在冰豆网上搜索。
信息论实验报告
信
息
论
实
验
报
告
计通学院
实验一:
唯一可译码判别准则
1、实验目的:
1进一步熟悉唯一可译码判别准则;
2掌握C语言字符串处理程序的设计和调试技术。
2、实验原理:
已知:
信源符号个数r、码字集合C
用下列步骤判断是否为唯一可译码:
①考察C中所有的码字,若Wi是Wj的前缀,则将相应的后缀作为一个尾随后缀码放入集合F0中;
②考察C和Fi两个集合,若Wi∈C是Wj∈Fi的前缀或者Wj∈Fi是Wi∈C的前缀,则将相应的后缀作为尾随后缀码放入集合Fi+1中;
③F=UiFi即为码C的尾随后缀集合;
④若F中出现了C中的元素,则算法终止,返回假(C不是唯一可译码);否则,若F中没有出现新的元素,则返回真。
3、实验环境:
windows;
visualbasic6.0;
4、实验代码:
存档名:
diyici
#include
#include
#include
structstrings
{
char*string;
structstrings*next;
};
structstringsFstr,*Fh,*FP;
//输出当前集合
voidoutputstr(strings*str)
{
do
{
cout<string<str=str->next;
}while(str);
cout<}
inlineintMIN(inta,intb)
{
returna>b?
b:
a;
}
inlineintMAX(inta,intb)
{
returna>b?
a:
b;
}
#definelength_a(strlen(CP))
#definelength_b(strlen(tempPtr))
//判断一个码是否在一个码集合中,在则返回0,不在返回1
intcomparing(strings*st_string,char*code)
{
while(st_string->next)
{
st_string=st_string->next;
if(!
strcmp(st_string->string,code))
return0;
}
return1;
}
//判断两个码字是否一个是另一个的前缀,如果是则生成后缀码
voidhouzhui(char*CP,char*tempPtr)
{
if(!
strcmp(CP,tempPtr))
{
cout<<"集合C和集合F中有相同码字:
"<<<<"不是唯一可译码码组!
"<exit
(1);
}
if(!
strncmp(CP,tempPtr,MIN(length_a,length_b)))
{
structstrings*cp_temp;
cp_temp=new(structstrings);
cp_temp->next=NULL;
cp_temp->string=newchar[abs(length_a-length_b)+1];
char*longstr;
longstr=(length_a>length_b?
CP:
tempPtr);//将长度长的码赋给longstr
//取出后缀
for(intk=MIN(length_a,length_b);kcp_temp->string[k-MIN(length_a,length_b)]=longstr[k];
cp_temp->string[abs(length_a-length_b)]=NULL;
//判断新生成的后缀码是否已在集合F里,不在则加入F集合
if(comparing(Fh,cp_temp->string))
{
FP->next=cp_temp;
FP=FP->next;
}
}
}
voidmain()
{
//功能提示和程序初始化准备
structstringsCstr,*Ch,*CP,*tempPtr;
Ch=&Cstr;
CP=Ch;
Fh=&Fstr;
FP=Fh;
charc[]="C:
";
Ch->string=newchar[strlen(c)];
strcpy(Ch->string,c);
Ch->next=NULL;
charf[]="F:
";
Fh->string=newchar[strlen(f)];
strcpy(Fh->string,f);
Fh->next=NULL;
//输入待检测码的个数
intCnum;
cout<<"输入待检测码的个数:
";
cin>>Cnum;
cout<<"输入待检测码"<for(inti=0;i{
cout<
";
chartempstr[10];
cin>>tempstr;
CP->next=new(structstrings);
CP=CP->next;
CP->string=newchar[strlen(tempstr)];
strcpy(CP->string,tempstr);
CP->next=NULL;
}
outputstr(Ch);
CP=Ch;
while(CP->next->next)
{
CP=CP->next;
tempPtr=CP;
do
{
tempPtr=tempPtr->next;
houzhui(CP->string,tempPtr->string);
}while(tempPtr->next);
}
outputstr(Fh);
structstrings*Fbegin,*Fend;
Fend=Fh;
while
(1)
{
if(Fend==FP)
{
cout<<"这是唯一可译码码组"<exit
(1);
}
Fbegin=Fend;
Fend=FP;
CP=Ch;
while(CP->next)
{
CP=CP->next;
tempPtr=Fbegin;
for(;;)
{
tempPtr=tempPtr->next;
houzhui(CP->string,tempPtr->string);
if(tempPtr==Fend)
break;
}
}
outputstr(Fh);//输出F集合中全部元素
}
}
5、实验结果及分析:
程序基本上满足要求。
实验二:
Huffman编码
1、实验目的:
(1)进一步熟悉Huffman编码过程;
(2)掌握C语言递归程序的设计和调试技术。
2、实验内容:
(1)输入:
信源符号个数r、信源的概率分布P;
(2)输出:
每个信源符号对应的Huffman编码的码字。
3、实验原理:
霍夫曼码是用概率匹配方法进行信源编码。
有两个明显特点:
一是保证了概率大的符号对应于短码,概率小的对应于长码,充分利用了短码;二是缩减信源的最后二个码字总是最后一位不同,从而保证了霍夫曼码是即时码。
霍夫曼变长码的效率很高,它可以单个信源符号编码或用L较小的信源序列编码,对编码器的设计来说也易实现。
4、实验代码及实验文件存档名:
实验环境:
Windows,MicrosoftvisualC++
文件存档名:
dierci
代码如下:
#include;
#include;
#include;
#include;
typedefstruct//构建结构体函数
{
unsignedintweight;
unsignedintparent,lchild,rchild;
}HTNode,*HuffmanTree;
typedefchar**HuffmanCode;
typedefstruct
{
unsignedints1;//变量名
unsignedints2;
}MinCode;
voidError(char*message);
HuffmanCodeHuffmanCoding(HuffmanTreeHT,HuffmanCodeHC,unsignedint*w,unsignedintn);
MinCodeSelect(HuffmanTreeHT,unsignedintn);//哈弗曼树函数
voidError(char*message)
{system("CLS");
fprintf(stderr,"Error:
%s\n",message);
exit
(1);
}
HuffmanCodeHuffmanCoding(HuffmanTreeHT,HuffmanCodeHC,unsignedint*w,unsignedintn)//利用霍夫曼树来实现编码函数
{
unsignedinti,s1=0,s2=0;
HuffmanTreep;
char*cd;
unsignedintf,c,start,m;
MinCodemin;
if(n<=1)Error("Codetoosmall!
");
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
for(p=HT,i=0;i<=n;i++,p++,w++)
{
p->weight=*w;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(;i<=m;i++,p++)
{
p->weight=0;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(i=n+1;i<=m;i++)
{
min=Select(HT,i-1);
s1=min.s1;
s2=min.s2;
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
printf("HTList:
\n");
for(i=1;i<=m;i++)
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
cd=(char*)malloc(n*sizeof(char*));
cd[n-1]='\0';
for(i=1;i<=n;i++)
{
start=n-1;
for(c=i,f=HT[i].parent;f!
=0;c=f,f=HT[f].parent)
if(HT[f].lchild==c)cd[--start]='0';
elsecd[--start]='1';
HC[i]=(char*)malloc((n-start)*sizeof(char*));
strcpy(HC[i],&cd[start]);
}
free(cd);
returnHC;
}
MinCodeSelect(HuffmanTreeHT,unsignedintn)//构建紧致码
{
unsignedintmin,secmin;
unsignedinttemp;
unsignedinti,s1,s2,tempi;//变量定义
MinCodecode;
s1=1;s2=1;
for(i=1;i<=n;i++)
if(HT[i].parent==0)
{
min=HT[i].weight;
s1=i;
break;
}
tempi=i++;
for(;i<=n;i++)
if(HT[i].weight{
min=HT[i].weight;
s1=i;
}
for(i=tempi;i<=n;i++)
if(HT[i].parent==0&&i!
=s1)
{
secmin=HT[i].weight;
s2=i;
break;
}
for(i=1;i<=n;i++)
if(HT[i].weight=s1&&HT[i].parent==0)
{
secmin=HT[i].weight;
s2=i;
}
if(s1>s2)
{
temp=s1;
s1=s2;
s2=temp;
}
code.s1=s1;
code.s2=s2;
returncode;
}
voidmain()//主函数体
{
HuffmanTreeHT=NULL;
HuffmanCodeHC=NULL;
unsignedint*w=NULL;
unsignedinti,n;
system("CLS");
printf("输入变量的个数:
\n");
scanf("%d",&n);
w=(unsignedint*)malloc((n+1)*sizeof(unsignedint*));
w[0]=0;
printf("输入相应概率对应的权值(即LOG值,底数为2),以回车键结束:
\n");
for(i=1;i<=n;i++)
{
printf("w[%d]=",i);
scanf("%d",&w[i]);
}
HC=HuffmanCoding(HT,HC,w,n);
for(i=1;i<=n;i++)
printf("%d\t\t%d\t\t%s\n",i,w[i],HC[i]);
}
5、实验结果及分析:
实验截图:
分析:
程序基本满足要求,通过数据结构学过的huffman树,利用权值构造了紧致码。