信息与编码理论实验报告.docx

上传人:b****8 文档编号:9551520 上传时间:2023-02-05 格式:DOCX 页数:18 大小:62.63KB
下载 相关 举报
信息与编码理论实验报告.docx_第1页
第1页 / 共18页
信息与编码理论实验报告.docx_第2页
第2页 / 共18页
信息与编码理论实验报告.docx_第3页
第3页 / 共18页
信息与编码理论实验报告.docx_第4页
第4页 / 共18页
信息与编码理论实验报告.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

信息与编码理论实验报告.docx

《信息与编码理论实验报告.docx》由会员分享,可在线阅读,更多相关《信息与编码理论实验报告.docx(18页珍藏版)》请在冰豆网上搜索。

信息与编码理论实验报告.docx

信息与编码理论实验报告

实验一:

唯一可译判决准则

1、实验目的

(1)进一步熟悉唯一可译判决准则;

(2)掌握C语言字符串处理程序的设计和调试技术。

2、实验要求

(1)已知:

信源符号个数

,码字集合

(2)输入:

任意一个码字集合

码字个数和每个具体的码字在运行时从键盘输入;

(3)输出:

判决(是唯一可译码/不是唯一可译码)。

3、算法

(1)设So为原始码字的集合,首先考察So中所有码字,如果So中有相同码字若码字,则不是唯一可译,停止;否则,若码字wj是码字wi的前缀,则将后缀列为S1中的元素;

(2)若产生的新集合为空,则为唯一可译,停止;否则转入步骤

(1)继续比较考察So和这个新的集合。

4、代码

#include

#include

#include

#include

#include

#defineTRUE1

#defineFALSE0

#defineOK1

#defineERROR0

#defineINFEASIBLE-1

#include"iostream.h"

typedefstructmazi

{

charzifu[10];

structmazi*next;

}QNode,*QueuePtr;

typedefstruct

{

QueuePtrfront;

QueuePtrrear;

}LinkQueue;

intInitQueue(LinkQueue&Q)//构造一个空的队列Q

{

Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));

if(!

Q.front)exit(OVERFLOW);

Q.front->next=NULL;

returnOK;

}

intQueueLength(LinkQueueQ)//求队列长

{

inti=0;

QueuePtrp;

p=Q.front;

while(Q.rear!

=p)

{

i++;

p=p->next;

}

returni;

}

intEnQueue(LinkQueue&Q,chari[])//插入字符串i为Q的新队尾元素

{

QueuePtrp;

p=(QueuePtr)malloc(sizeof(QNode));

if(!

p)exit(OVERFLOW);

strcpy(p->zifu,i);

p->next=NULL;

Q.rear->next=p;

Q.rear=p;

returnOK;

}

intClearQueue(LinkQueue&Q)//清空队列

{

QueuePtrp,q;

Q.rear=Q.front;

p=Q.front->next;

Q.front->next=NULL;

while(p)

{

q=p;

p=p->next;

free(q);

}

returnOK;

}

intbijiao(LinkQueue&Q,LinkQueue&R,LinkQueue&S)//比较Q和R存入队列S中

{

QueuePtrq,r;

inti,flag=1;

q=Q.front->next;

while(q)

{

r=R.front->next;

while(r)

{

if(strcmp(q->zifu,r->zifu)==0)flag=0;//不是唯一可译码

r=r->next;

}

q=q->next;

}

if(flag)

{

q=Q.front->next;

while(q)

{

r=R.front->next;

while(r)

{

if(strlen(q->zifu)!

=strlen(r->zifu))

{

i=strlen(q->zifu)zifu)?

strlen(q->zifu):

strlen(r->zifu);

if(strncmp(q->zifu,r->zifu,i)==0)

{

chars[10],t[10];

if(strlen(q->zifu)zifu))

{

strcpy(s,r->zifu);

s[strlen(r->zifu)]='\0';

i=strlen(r->zifu)-strlen(q->zifu);

}

else

{

strcpy(s,q->zifu);

s[strlen(q->zifu)]='\0';

i=strlen(q->zifu)-strlen(r->zifu);

}

strrev(s);

strncpy(t,s,i);

t[i]='\0';

strrev(t);

EnQueue(S,t);

}

}

r=r->next;

}

q=q->next;

}

}

if(QueueLength(S))

{

ClearQueue(R);

flag=bijiao(Q,S,R);

}

returnflag;

}

intbijiao(LinkQueue&Q,LinkQueue&R)//队列Q自己比较,存入R中

{

QueuePtrq,r;

inti,flag=2;

q=Q.front->next;

while(q)

{

r=q->next;

while(r)

{

if(strcmp(q->zifu,r->zifu)==0)

{

flag=0;//不是唯一可译码

}

r=r->next;

}

q=q->next;

}

if(flag)

{

q=Q.front->next;

while(q)

{

r=q->next;

while(r)

{

if(strlen(q->zifu)!

=strlen(r->zifu))

{

i=strlen(q->zifu)zifu)?

strlen(q->zifu):

strlen(r->zifu);

if(strncmp(q->zifu,r->zifu,i)==0)

{

chars[10],t[10];

if(strlen(q->zifu)zifu))

{

strcpy(s,r->zifu);

s[strlen(r->zifu)]='\0';

i=strlen(r->zifu)-strlen(q->zifu);

}

else

{

strcpy(s,q->zifu);

s[strlen(q->zifu)]='\0';

i=strlen(q->zifu)-strlen(r->zifu);

}

strrev(s);

strncpy(t,s,i);

t[i]='\0';

strrev(t);

EnQueue(R,t);

}

}

r=r->next;

}

q=q->next;

}

}

if(flag&&!

QueueLength(R))flag=1;//唯一可译

returnflag;

}

voidmain()

{

LinkQueues0,s1,s2;

inti,N;

chars[10];

InitQueue(s0);

InitQueue(s1);

InitQueue(s2);

cout<<"请输入码字个数N:

";

cin>>N;

cout<<"请输入各码字:

";

for(i=0;i

{

cin>>s;

EnQueue(s0,s);

}

if(bijiao(s0,s1)==0)cout<<"不是唯一可译码"<

elseif(bijiao(s0,s1)==1)cout<<"是唯一可译码"<

else

{

if(bijiao(s0,s1,s2)==0)cout<<"不是唯一可译码"<

elsecout<<"是唯一可译码"<

}

}

5、测试结果

实验二:

Huffman编码

1、实验目的

(1)进一步熟悉Huffman编码过程;

(2)掌握C语言递归程序的设计和调试技术。

2、实验要求

(1)输入:

信源符号个数r、信源的概率分布P;

(2)输出:

每个信源符号对应的Huffman编码的码字。

3、算法

(1)将信源U的n符号中个概率中两个概率最小的符号合并成一个新符号,新符号的概率为两个符号概率之和,得到只包含n-1个符号的缩减信源U1;

(2)依次继续,直至信源最后只剩下一个符号为止;

(3)将每次合并的两个信源符号分别用0和1码符号表示;

(4)从最后一级缩减信源开始,向前返回,就得出各信源符号所对应的码符号序列,即得各信源符号对应的码字。

4、代码

#include

#include

#include

typedefstruct{

unsignedfloatweight;

unsignedintparent,lchild,rchild;

}HTNode,*HuffmanTree;//动态分配数组存储赫夫曼树

typedefchar**HuffmanCode;//动态分配数组存储赫夫曼编码表

voidHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,float*w,intn)

{//w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC。

if(n<1)return;

voidSelect(HuffmanTreeHT,inta,int&a1,int&a2);

HuffmanTreep;

inti,s1,s2,f,c,m,start;

char*cd;

m=2*n-1;

HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元为空

for(p=HT+1,i=1;i<=n;i++,p++,w++)

{

p->weight=*w;p->parent=0;

p->lchild=0;p->rchild=0;

}

for(i=n+1;i<=m;i++,p++)

{

p->weight=0;p->parent=0;

p->lchild=0;p->rchild=0;

}

for(i=n+1;i<=m;i++){//建赫夫曼树

//在HT[1..i-1]选择parent为0且weight最小的两个结点,其序号分别为s1和s2.

Select(HT,i-1,s1,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;

}

//从叶子到根逆向求每个字符的赫夫曼编码

HC=(HuffmanCode)malloc((n+1)*sizeof(char*));//分配n个字符编码的头指针向量

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));//为第i个字符编码分配空间

strcpy(HC[i],&cd[start]);//从cd复制编码(串)到HC

}

free(cd);//释放工作空间

}

voidSelect(HuffmanTreeHT,inta,int&a1,int&a2)

{

intj;

intmin1;

intmin2;

for(j=1;j<=a;j++)

if(HT[j].parent==0)

{

min1=HT[j].weight;

a1=j;

break;

}

for(j=1;j<=a;j++)

{

if(HT[j].parent==0&&HT[j].weight

{

min1=HT[j].weight;

a1=j;

}

}

for(j=1;j<=a;j++)

if(HT[j].parent==0&&j!

=a1)

{

min2=HT[j].weight;

a2=j;

break;

}

for(j=1;j<=a;j++)

{

if(HT[j].parent==0&&HT[j].weight

=a1)

{

min2=HT[j].weight;

a2=j;

}

}

}

voidmain()

{

float*w;

intn,i;

HuffmanTreeHT;

HuffmanCodeHC;

HT=NULL;

HC=NULL;

printf("请输入信源符号个数n:

");

scanf("%d",&n);

w=(float*)malloc(n*sizeof(float));

printf("请依次输入各信源符号的概率:

");

for(i=0;i

HuffmanCoding(HT,HC,w,n);

for(i=0;i

printf("第%d个信源符号的概率为%f,赫夫曼编码为:

%s\n",i+1,w[i],HC[i+1]);

}

5、测试结果

实验三:

LZW编码

1、实验目的:

(1)进一步熟悉通用编码算法;

(2)掌握C语言程序设计和调试过程中数值的进制转换、数值与字符串之间的转换等技术。

2、实验要求:

(1)输入:

本程序将从标准输入中读入待压缩的数据流;

(2)输出:

将压缩结果输出到标准输出上去。

3、算法:

(1)将待编码信源序列中的所有单个字符存入串表中,并给每个符号赋一个码字值;

(2)读入第一个输入字符,赋给前缀变量P;

(3)读入下一个输入字符,赋给前缀变量S;

(4)如果S为空,输出P,停止;否则执行步骤5;

(5)如果PS不在串表中,则将P对应的码字值输出,将PS存入串表,并分配一个码字值,同是将扩展字符S赋给P;否则将PS赋给P;

4、代码:

#include"stdio.h"

#include"stdlib.h"

#include"string.h"

#include"iostream.h"

typedefstructzifu

{

chara[30];

};

voidmain()

{

structzifu*x,*y;

inti,j,k,N,flag;

chars[30],p[30],q[30],z[30];

cout<<"请输入信源个数:

";

cin>>N;

x=y=(zifu*)malloc(N*sizeof(zifu));

cout<<"请输入信源序列:

";

for(i=0;i>x[i].a;

for(i=0;i

k=0;

strcpy(y[0].a,x[0].a);

for(i=1;i

{

flag=1;

for(j=0;j<=k;j++)if(strcmp(y[j].a,x[i].a)==0)flag=0;

if(flag)

{

k++;

strcpy(y[k].a,x[i].a);

}

}

cout<<"可将信源编码为:

"<

strcpy(p,&z[0]);

p[1]='\0';

for(i=1;i

{

strcpy(s,&z[i]);

s[1]='\0';

flag=1;

strcpy(q,p);

strcat(q,s);

for(j=0;j<=k;j++)if(strcmp(q,y[j].a)==0)flag=0;

if(flag)

{

k++;

strcpy(y[k].a,q);

for(j=0;j

strcpy(p,s);

}

else

{

strcpy(p,q);

}

}

for(j=0;j<=k;j++)if(strcmp(p,y[j].a)==0)cout<

cout<<"输出字符串序列:

"<

for(j=0;j<=k;j++)cout<

}

5、测试结果

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 调查报告

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1