程序设计题目三

题目3  

     

在一个加密应用中,要处理的信息来自下面的字符集,各个字符的相关使用频度如下:

 

字符空格 A  B  C  D   E F  G   H  I   J  K  L M

频度 180 64 13 23  32103 22 15   47 57  1 5  31  20

字符 N O  P   Q  R  S T   U  V  W X Y  Z 

频度 55 63  15 1 48  56  80 25 7  18  2  16  1

现请编写程序你实现如下功能:

 

1)运行时,由用户输入来初始化字符集大小和相应用字符。

 

2)输入一个要加密的字符串,将其加密。

 

3)输出解密字符串。

代码

#include<stdio.h>
#define N 27       //空格+26个大写字母
#define M 2*N-1
#define infinity 32767

struct node                //huffman树的结点结构
{

       int weight;            //结点权值

       int prents,lchild,rchild;           //双亲,左孩子,右孩子
};
struct codetype           //huffman编码结构
{

       int start;               //起始位置

       char bits[N+1];        //存放0,1的数组

};
struct element            //字符及其编码的结构
{

       char symbol;             //字符

       struct codetype code;         //字符编码

};
struct node tree[M+1];            //n个结点的huffman树
struct element user[N+1],t[100];        //n个结点的huffman编码表,用户编码
int x1,x2;
void sethuftree();                   //有关函数声明

void select0(int s);

void sethufcode();

void setcode();

void printtree();

void printhufcode();

void  Decrypt();
void Encryptor();
void main()                     //**********主函数**********

{

       sethuftree();

       printtree();

       sethufcode();

       printhufcode();

       setcode();

       printf("\n\n");

}
void sethuftree()       //建立huffuman树

{

       int i,treeweight[N]={180,64,13,23,32,103,22,15,47,57,1,5,31,20,55,63,15,1,48,56,80,25,7,18,2,16,1};

       char usersymbol[N]={' ','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

      

       for(i=1;i<=M;i++)                   //初始双亲,左,右结点为:0

              tree[i].prents=tree[i].lchild=tree[i].rchild=0;

       for(i=1;i<=N+1;i++)        //初始化27个字符及其权值

       {

              user[i].symbol=usersymbol[i-1];

              tree[i].weight=treeweight[i-1];

       }

       for(i=N+1;i<=M;i++)               //找权值最小的2个结点,组成huffman树

       {

              select0(i-1);            //调用找权值最小的2个结点函数

              tree[x1].prents=i;

              tree[x2].prents=i;

              tree[i].lchild=x1;

              tree[i].rchild=x2;

              tree[i].weight=tree[x1].weight+tree[x2].weight;

       }

}
void select0(int s)              //找权值最小的2个结点
{

       int i;

       float v1,v2;

       v1=v2=infinity;

       x1=x2=0;

       for(i=1;i<=s;i++)

              if(tree[i].prents==0)

                     if(tree[i].weight<v1)

                     {

                            v2=v1;

                            x2=x1;

                            v1=tree[i].weight;

                            x1=i;

                     }

                     else if(tree[i].weight<v2)

                     {

                            v2=tree[i].weight;

                            x2=i;

       }

}
void printtree()            //输出huffman树
{

       int i;
       printf("哈夫曼树为:\n\n");

       printf("结点值 权值(频度) 双亲   左孩子  右孩子\n");

       for(i=1;i<=N;i++)

              printf("  %-8c%-11d%-8d%-8d%d\n",user[i].symbol,tree[i].weight,tree[i].prents,tree[i].lchild,tree[i].rchild);

       for(i=N+1;i<=M;i++)

              printf("\t  %-11d%-8d%-8d%d\n",tree[i].weight,tree[i].prents,tree[i].lchild,tree[i].rchild);

       printf("\n\n------------------------------------------------------------------\n\n\n");

}
void sethufcode()           //建立huffman编码

{

       int i,s,f,k=1;

       struct codetype c;

       for(i=1;i<=N;i++)

       {

              c=user[i].code;

              c.start=N+1;

              s=i;

              f=tree[s].prents;

              do

              {

                     c.start--;

                     if(s==tree[f].lchild)

                            c.bits[c.start]='0';

                     else

                            c.bits[c.start]='1';

                     s=f;

                     f=tree[s].prents;

              }while(f);

              user[i].code=c;

       }

}
void printhufcode()                   //输出huffman编码,即空格+26个大写字母
{

       int i,j;

       struct codetype c;

       printf("编码为:\n");

       for(i=1;i<=N;i++)

       {

              printf("%c:",user[i].symbol);

              c=user[i].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf("\n");

       }

       printf("\n\n--------------------------------------------------------------------\n\n");
}
void setcode()                  //对字符进行编码

{

       int i,j,count;

       char c0,k='Y';

       struct codetype c;

       while(k=='Y')                   //利用循环,实现对字符多次编码

       {

       printf("\n\n请输入字符(大写字母+空格,不超过100),输入'.'(+回车)号结束\n\n");

       for(i=1;i<=100;i++)           //利用循环,实现对字符输入

       {

              c0=getchar();

              t[i].symbol=c0;

              if(c0=='.') break;

       }
       count=i;                           //记录字符个数
       printf("\n\n--------------------------------------------------------------------\n\n");
       printf("\n\n字符编码为:\n\n");
	   for(i=1;i<=count;i++)               //利用循环,实现对字符输出
	   {

              if(t[i].symbol=='.')break;

              else

              switch(t[i].symbol)            //利用开关语句,查找编码

              {

       case ' ':

              c=user[1].code;

              for(j=c.start;j<=N;j++)               //输出编码

                     printf("%C",c.bits[j]);

              printf(" ");

              break;
       case 'A':

              c=user[2].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'B':

              c=user[3].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'C':

              c=user[4].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;
	   case 'D':

              c=user[5].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;
	   case 'E':

              c=user[6].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'F':

              c=user[7].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'G':

              c=user[8].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'H':

              c=user[9].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'I':

              c=user[10].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'J':

              c=user[11].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'K':

              c=user[12].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'L':

              c=user[13].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'M':

              c=user[14].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'N':

              c=user[15].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'O':

              c=user[16].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'P':

              c=user[17].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'Q':

              c=user[18].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'R':

              c=user[19].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'S':

              c=user[20].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'T':

              c=user[21].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'U':

              c=user[22].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'V':

              c=user[23].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'W':

              c=user[24].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'X':

              c=user[25].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'Y':

              c=user[26].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       case 'Z':

              c=user[27].code;

              for(j=c.start;j<=N;j++)

                     printf("%c",c.bits[j]);

              printf(" ");

              break;

       default:

              printf("  *此编码找不到,请检查输入是否正确*  ");

              }

       }

       printf("\n\n\n--------------------------------------------------------------------\n\n");

       printf("\n\n\n-----   继续??(Y/N)  -----\n");

	   getchar();

       printf("\n");

       scanf("%c",&k);

       getchar();

       printf("\n\n*********************************************************\n\n");

       }








评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值