帮别人改的DS课设5

#include<iostream.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int s1,s2,selfnumber;        //s1,s2存储最小和次小的两个结点,selfnumber存储出现字符个数


//构造HuffmanTree类型
typedef struct       
{
 char self;        //字符存储
 int weight;        //权值存储
 int parent ,lchild,rchild;        //结点存储
 int bl;        //存在判断
}HuffmanTree;


//构Huffman编码临时存储类型
typedef struct
{
 char cd[900];        //编码临时存储
 int start;        //编码起始点
}HuffmanCode;


//存储Huffman编码
typedef struct
{
 char self;        //字符存储
 char code[900];        //编码存储
}codesaver;


//字符->编码,编码->字符的查询
void codesearch(codesaver cd[])
{
 char c,ch[900],ch1;        //ch1存储要查询的字符,ch[]存储要查询的编码,c作判断
 int i;
 while(1)
 {
  cout<<"/n Press 'c' to search the char/n"<<endl;
  cout<<"/n Press 'd' to search the code/n"<<endl;
  cout<<"/n Press other to exit/n"<<endl;
  cin>>"%c">>&c;
  getchar();
  if(c=='c')
  {
   cout<<"/n Input the char :"<<endl;
   cin>>"%c">>&ch1;        //输入要查询的字符
   getchar();
   for(i=0;i<selfnumber;i++)
   {
    if(cd[i].self==ch1)        //如遇相同则打印,否则退出
    {
     cout<<"/n The code is : %s/n"<<cd[i].code<<endl;
     break;
    }
    if(i==selfnumber-1)
    {
     cout<<"/n Not find!/n"<<endl;
    }
   }
  }
  else if(c=='d')
  {
   cout<<"/n Input the code :"<<endl;
   cin>>"%s">>ch;        //输入要查询的编码
   getchar();
   for(i=0;i<selfnumber;i++)
   {
    if(strcmp(cd[i].code,ch)==0)        //如遇相同则打印,否则退出
    {
     cout<<"/n The char is : %c/n"<<cd[i].self<<endl;
     break;
    }
    if(i==selfnumber-1)
    {
     cout<<"/n Not find!/n"<<endl;
    }
   }
  }
  else
  {
   break;
  }
 }
 return;
}


//打印Huffman编码
void PrintHuffmanCode(HuffmanTree tree[],HuffmanCode code[],codesaver cd[])
{
 int i,j,k;
 cout<<"/n Print Huffman Code:/n"<<endl;
 for(i=0;i<selfnumber;i++)
 {
  cout<<" %c :"<<tree[i].self<<endl;        //打印字符
   cd[i].self=tree[i].self;
    j=0;
  for(k=code[i].start;k<=selfnumber;k++)        //打印编码
  {
   cout<<" %c "<<code[i].cd[k]<<endl;
   cd[i].code[j]=code[i].cd[k];
   cd[i].code[j+1]=0;
   j++;
  }
  cout<<"/n";
 }
}


//构造Huffman编码
void CreateHuffmanCode(HuffmanTree tree[],HuffmanCode code[])
{
 int i,f,c;
 HuffmanCode d;
 for(i=0;i<selfnumber;i++)
 {
  d.start=selfnumber+1;
  c=i;
  f=tree[i].parent;
  while(f!=0)
  {
   if(tree[f].lchild==c)        //左转为0
    d.cd[--d.start]='0';
   else
    d.cd[--d.start]='1';        //右转为1
   c=f;
   f=tree[f].parent;
  }
  code[i]=d; 
 }
}


//找寻parent为0,权最小的两个节点
void select(HuffmanTree tree[],int k) 
{
 int i;
 for (i=0;i<=k && tree[i].parent!=0 ;i++); s1=i;        //判断双亲是否为0
 //寻找最小和次小结点
 for (i=0;i<=k;i++)
  if (tree[i].parent==0 && tree[i].weight<tree[s1].weight) s1=i;
  for (i=0; i<=k ; i++)
   if (tree[i].parent==0 && i!=s1) break; s2=i;
   for (i=0;i<=k;i++)
    if ( tree[i].parent==0 && i!=s1 && tree[i].weight<tree[s2].weight) s2=i;
}


//生成HuffmanTree
void CreateHuffmanTree(HuffmanTree tree[],int *w)

 int m,i;
 m=2*selfnumber-1;        //m为结点个数
 for (i=0;i<selfnumber;i++)        //初始化树但保留权值
 {
  tree[i].parent=0;
  tree[i].lchild=0;
  tree[i].rchild=0;
 }
 for (i=selfnumber+1;i<=m;i++)
 { 
  tree[i].parent=0;
  tree[i].lchild=0;
  tree[i].rchild=0;
 }
 for (i=selfnumber+1;i<=m;i++)
 {
  select(tree, i-1);        //寻找最小和次小结点
  tree[s1].parent=i;
  tree[s2].parent=i;
  tree[i].lchild=s1;
  tree[i].rchild=s2;    
  tree[i].weight =tree[s1]. weight+ tree[s2].weight;        //新结点权值等于最小和次小相加
 }
}


//根据字符出现次数进行权值累加
void weightadd(HuffmanTree tree[95]) 
{
 FILE *fp;
 char name[900],ch;
 int i;
 while(1)      
 {
  cout<<"/n Input the file name:"<<endl;
  cin>>name;
  fp=fopen(name,"r");
  if(fp==NULL)        //判断文件是否为空
  {
   cout<<"/n The file can not be find!/n"<<endl;
  }
  else
   break;
 }
 cout<<"/n"<<endl;
 while(!feof(fp))        //读文件
 {
  ch=fgetc(fp);
  cout<<"%c"<<ch<<endl;
  for(i=0;i<95;i++)
  {
   if(tree[i].self==ch)        //如遇相同字符则自加一次
   {
    tree[i].weight++;
    tree[i].bl=1;
   
   }
  }
 }
 cout<<"/n"<<endl;
 fclose(fp);
 for(i=0;i<95;i++)        //统计文章中字符个数存入selfnumber中
 {
  if(tree[i].bl==1)
   selfnumber++;
 }
 
};
int main(int argc, char* argv[])
{
 while(1)
 {
  int i,w[95],j=0;
  HuffmanTree tree[95],newtree[95];        //95为字符种类最大数
  HuffmanCode code[95];
  codesaver cd[95];
  selfnumber=0;
  for(i=32;i<=126;i++)        //HuffmanTree的初始化赋值
  {
   tree[i-32].self=i;
   tree[i-32].weight=0;
   tree[i-32].parent=0;
   tree[i-32].lchild=0;
   tree[i-32].rchild=0;
   tree[i-32].bl=0;
  }
  for(i=0;i<95;i++)
  {
   w[i]=tree[i].weight;
  }
 
  weightadd(tree);        //调用函数进行权值累加
  cout<<"/n";
  if(selfnumber!=0&&selfnumber!=1)
  {
  for(i=0;i<95;i++)
  {
   w[i]=tree[i].weight;
  }
  for(i=0;i<95;i++)        //将出现的字符存入新树中
  {
   if(tree[i].bl==1)
   {
    newtree[j].self=tree[i].self;
    newtree[j].weight=tree[i].weight;
    newtree[j].parent=0;
    newtree[j].lchild=0;
    newtree[j].rchild=0;
    j++;
   }
  }
  CreateHuffmanTree(newtree,w);        //构造HuffmanTree
  CreateHuffmanCode(newtree,code);        //构造Huffman编码
  PrintHuffmanCode(newtree,code,cd);        //打印Huffman编码
  codesearch(cd);        //对字符和编码的查找
  }
  else
  {
   cout<<"/n There is on or only one words in it!/n"<<endl;
  }
 }
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值