2023年全國(guó)碩士研究生考試考研英語(yǔ)一試題真題(含答案詳解+作文范文)_第1頁(yè)
已閱讀1頁(yè),還剩25頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、<p>  文件加密-赫夫曼算法</p><p><b>  一 目的</b></p><p>  通過(guò)課程設(shè)計(jì),鞏固和加深對(duì)線(xiàn)性表、棧、隊(duì)列、字符串、樹(shù)、圖、查找、排序等理論知識(shí)的理解;掌握現(xiàn)實(shí)復(fù)雜問(wèn)題的分析建模和解決方法(包括問(wèn)題描述、系統(tǒng)分析、設(shè)計(jì)建模、代碼實(shí)現(xiàn)、結(jié)果分析等);提高利用計(jì)算機(jī)分析解決綜合性實(shí)際問(wèn)題的基本能力。</p>&

2、lt;p><b>  二 需求分析</b></p><p>  1、文件加密核心算法(赫夫曼編碼)設(shè)計(jì)</p><p>  文件加密的核心算法是赫夫曼編碼,赫夫曼編碼的完成首先建立在赫夫曼樹(shù)的創(chuàng)建,在此之前要完成編碼字符的權(quán)值計(jì)算,依照題意:</p><p>  1、將26個(gè)字符的權(quán)值存入weight結(jié)構(gòu)體中。</p>&

3、lt;p>  2、將各個(gè)結(jié)點(diǎn)HTNode補(bǔ)充數(shù)值,創(chuàng)建赫夫曼樹(shù)HuffmanTree。</p><p>  3、赫夫曼樹(shù)創(chuàng)建完畢,即可進(jìn)行字符串的編碼和解碼工作。核心算法即完成。</p><p><b>  2、功能要求和說(shuō)明</b></p><p>  使用菜單操作,提示用戶(hù)相應(yīng)的操作,用戶(hù)指定文件對(duì)其進(jìn)行加密或解密,在屏幕上可以看到文

4、件內(nèi)容。</p><p>  用戶(hù)指定文件,默認(rèn)在D:\,為了便于測(cè)試編碼和解碼的正確性??梢杂捎脩?hù)輸入字符串進(jìn)行編碼和解碼。</p><p><b>  三 概要設(shè)計(jì)</b></p><p>  1、可滿(mǎn)足輸入輸出的形式及限制</p><p>  本程序只支持26字符編碼解碼,程序運(yùn)行中間會(huì)產(chǎn)生一個(gè)outfile.t

5、xt文件,用于存儲(chǔ)加密或解密內(nèi)容。支持用戶(hù)在屏幕查看文件內(nèi)容。</p><p>  程序在用戶(hù)輸入數(shù)據(jù)前,會(huì)輸出相應(yīng)的提示,在用戶(hù)輸入超出范圍或者輸入錯(cuò)誤時(shí),會(huì)提示重新輸入或者提示錯(cuò)誤并退出。</p><p>  2、所用數(shù)據(jù)類(lèi)型的定義及含義</p><p>  此程序運(yùn)用了整形、實(shí)型、字符型、指針、數(shù)組、結(jié)構(gòu)體。下面是全局(舉例):</p><

6、p>  typedef struct{</p><p>  int weight;</p><p>  int parent,lchild,rchild;</p><p>  }HTNode; //構(gòu)造赫夫曼樹(shù)結(jié)點(diǎn)的結(jié)構(gòu)體</p><p>  typedef struct{</p><p

7、>  HTNode *HTN; //存儲(chǔ)編碼的各個(gè)字符</p><p>  int length; //需編碼字符個(gè)數(shù)</p><p>  int size; //赫夫曼編碼總?cè)萘?lt;/p><p>  }HuffmanTree; //構(gòu)造赫夫曼樹(shù)的結(jié)構(gòu)體</p>&

8、lt;p>  typedef struct{</p><p>  char *ch; //存放需要編碼的原始字碼</p><p>  int *in; //存放各個(gè)字碼的權(quán)值</p><p><b>  }Weight; </b></p><p>  cha

9、r Code[27][26]; //存放各個(gè)字符的赫夫曼編碼01</p><p>  int Code_N[30]; //存放各個(gè)字符對(duì)應(yīng)編碼01的個(gè)數(shù),用于輸出控制</p><p><b>  3、各模塊的劃分</b></p><p><b>  簡(jiǎn)化圖:</b></p><

10、p>  4、各模塊的功能描述</p><p>  1、赫夫曼編碼部分:題意規(guī)定字符頻率或用戶(hù)輸入字符串,計(jì)算出字符權(quán)值,創(chuàng)建赫夫曼樹(shù),進(jìn)行赫夫曼編碼,將其存入全局變量,用于字符串編碼解碼,文件加密及解密。</p><p>  2、文件加密部分:由用戶(hù)輸入加密的文件名稱(chēng)(filename.txt),加密過(guò)程中將加密后內(nèi)容暫時(shí)存入outfile.txt中,此時(shí)已經(jīng)將filename.tx

11、t中內(nèi)容加密,但內(nèi)容在outfile.txt中,重新將outfile.txt內(nèi)容存入到filename.txt中,則文件加密過(guò)程完成。</p><p>  3、文件解密部分:文件解密過(guò)程同加密過(guò)程,只是內(nèi)容處理只是由加密變?yōu)榻饷苓^(guò)程。其余過(guò)程不改變,解密過(guò)程也用到了outfile.txt文件。</p><p>  4、文件查看部分:用戶(hù)輸入文件名稱(chēng),文件內(nèi)容輸出到屏幕,用于查看文件加密或解

12、密的結(jié)果。</p><p>  5、各函數(shù)的定義及描述</p><p>  void showMenu(); //輸出菜單列表</p><p>  操作結(jié)果:在屏幕上打印出菜單</p><p>  void Init_Huf

13、fmanTree(HuffmanTree &H,Weight S); //對(duì)赫夫曼樹(shù)結(jié)構(gòu)初始化</p><p>  H是初始化的赫夫曼樹(shù)的結(jié)構(gòu)體,S是字符及權(quán)值的結(jié)構(gòu)體</p><p>  操作結(jié)果:對(duì)H和S進(jìn)行了初始化</p><p>  void Init_Weight(Weight &S,int msize,int msize1);

14、//對(duì)編碼個(gè)數(shù)和權(quán)值的結(jié)構(gòu)初始化</p><p>  S是傳入函數(shù)的字符及權(quán)值的結(jié)構(gòu)體</p><p>  msize和msize1是初始化S.ch和S.in的整形數(shù)據(jù)</p><p>  操作結(jié)果:將Weight結(jié)果體初始化</p><p>  void WeightNumber(Weight &S);

15、 //求出輸入字符串各個(gè)字符的權(quán)值</p><p>  S是傳入的的Weight結(jié)構(gòu)體</p><p>  操作結(jié)果:S的數(shù)值按照程序重新計(jì)算字符權(quán)值</p><p>  void select(HuffmanTree H,int j,int a[]); //選擇parent=0且權(quán)值較小的兩個(gè)HTn

16、ode</p><p>  H是HuffmanTree結(jié)構(gòu)體傳入數(shù)值,a[]用來(lái)返回兩個(gè)較小權(quán)值的下標(biāo)</p><p>  操作結(jié)果:a[]存入了在j個(gè)數(shù)據(jù)中較小權(quán)值的結(jié)點(diǎn)下標(biāo)</p><p>  void creat_HuffmanTree(HuffmanTree &H); //創(chuàng)建赫夫曼樹(shù)</p><p> 

17、 H是HuffmanTree結(jié)構(gòu)體。</p><p>  操作結(jié)果:H構(gòu)建好了赫夫曼樹(shù)</p><p>  void creat_HTCode(HuffmanTree H,Weight S); //赫夫曼編碼</p><p>  操作結(jié)果:輸出各個(gè)字符編碼并存入code[][]中。</p><p>  void explain_H

18、TCode(HuffmanTree H,Weight S); //用戶(hù)輸入01字符串進(jìn)行赫夫曼解碼</p><p>  輸入內(nèi)容:輸入01字符串</p><p>  操作結(jié)果:輸出對(duì)01字符串按照赫夫曼編碼對(duì)應(yīng)的字符串</p><p>  void encryptFile(Weight S);

19、 //對(duì)指定文件進(jìn)行加密</p><p>  操作結(jié)果:文件內(nèi)容變?yōu)榘凑蘸辗蚵幋a規(guī)則的01字符內(nèi)容</p><p>  void deencryptFile(HuffmanTree H,Weight S); //對(duì)指定文件進(jìn)行解密</p><p>  操作結(jié)果:加密內(nèi)容變?yōu)榘凑蘸辗蚵幋a規(guī)則對(duì)應(yīng)的字符內(nèi)容</p><p>

20、;  void my_readFile(); //用于讀出文件中所儲(chǔ)存的全部信息</p><p>  操作結(jié)果:在屏幕上輸出指定文件內(nèi)容</p><p>  6、各函數(shù)之間的調(diào)用關(guān)系</p><p>  主函數(shù)中是菜單打?。╯howmenu ())和switch()

21、,各模塊套用和調(diào)用關(guān)系如下:</p><p>  主函數(shù)中調(diào)用Init_HuffmanTree(h,s); creat_HuffmanTree(h); creat_HTCode(h,s);</p><p>  explain_HTCode(h,s); encryptFile(s); deencryptFile(h,s); WeightNumber(s);</p><p

22、>  子函數(shù)creat_HuffmanTree(h);中調(diào)用了select(HuffmanTree H,int j,int a[]);</p><p><b>  四 詳細(xì)設(shè)計(jì)</b></p><p><b>  1、流程圖</b></p><p><b>  2、數(shù)據(jù)類(lèi)型及定義</b><

23、;/p><p>  1、此程序運(yùn)用了整形、實(shí)型、字符型、指針、文件指針、數(shù)組、結(jié)構(gòu)體。</p><p>  2、全局變量的數(shù)據(jù)類(lèi)型</p><p>  typedef struct{</p><p>  int weight;</p><p>  int parent,lchild,rchild;</p>&

24、lt;p>  }HTNode; //構(gòu)造赫夫曼樹(shù)結(jié)點(diǎn)的結(jié)構(gòu)體</p><p>  typedef struct{</p><p>  HTNode *HTN; //存儲(chǔ)編碼的各個(gè)字符</p><p>  int length; //需編碼字符個(gè)數(shù)</p><p>  int si

25、ze; //赫夫曼編碼總?cè)萘?lt;/p><p>  }HuffmanTree; //構(gòu)造赫夫曼樹(shù)的結(jié)構(gòu)體</p><p>  typedef struct{</p><p>  char *ch; //存放需要編碼的原始字碼</p><p>  int *in;

26、 //存放各個(gè)字碼的權(quán)值</p><p><b>  }Weight; </b></p><p>  char Code[27][26]; //存放各個(gè)字符的赫夫曼編碼01</p><p>  int Code_N[30]; //存放各個(gè)字符對(duì)應(yīng)編碼01的個(gè)數(shù),用于輸出控制</p>

27、;<p><b>  3、數(shù)據(jù)的定義聲明</b></p><p>  主函數(shù)中定義了:HuffmanTree h; //用于構(gòu)建赫夫曼樹(shù)</p><p>  Weight s; //用于存放各個(gè)字符的權(quán)值</p><p>  3、主要程序的源代碼(部分)及注釋</p><p>  //

28、對(duì)赫夫曼樹(shù)結(jié)構(gòu)初始化</p><p>  void Init_HuffmanTree(HuffmanTree &H,Weight S){</p><p>  H.HTN=new HTNode[S.in[0]*2-1];</p><p>  for(int i=1;i<=S.in[0]*2-1;i++){ //將H.HTN[i]權(quán)值、父親節(jié)點(diǎn)、左右孩

29、子都設(shè)置為0</p><p>  H.HTN[i].weight=0;</p><p>  H.HTN[i].parent=0;</p><p>  H.HTN[i].lchild=0;</p><p>  H.HTN[i].rchild=0; </p><p><b>  }<

30、;/b></p><p>  for(int j=1;j<=S.in[0];j++){</p><p>  H.HTN[j].weight=S.in[j];</p><p>  } </p><p>  H.length=S.in[0];

31、 //需要編碼的字符個(gè)數(shù)</p><p>  H.size=S.in[0]*2-1; //赫夫曼編碼容量為2*n-1,n為編碼字符個(gè)數(shù)</p><p><b>  }</b></p><p>  //對(duì)編碼個(gè)數(shù)和權(quán)值的結(jié)構(gòu)初始化</p><p>  void Init_Weig

32、ht(Weight &S,int msize,int msize1){</p><p>  S.ch=new char[msize];</p><p>  S.in=new int[msize1];</p><p>  if(!S.ch&&!S.in){</p><p>  cout<<"未能分配

33、空間!"<<endl;</p><p>  getchar();</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  //求出輸入

34、字符串各個(gè)字符的權(quán)值</p><p>  void WeightNumber(Weight &S){</p><p>  char s[50];</p><p>  int i=0,j=1,k=1;</p><p>  for(i=0;i<50;i++)</p><p>  S.in[i]=0;</

35、p><p>  printf("請(qǐng)輸入要編碼的字符串(0-50):\n");</p><p>  gets(s); //輸入字符串</p><p>  while(s[i]!='\0'){</p><p><

36、b>  j=1;</b></p><p>  while(S.ch[j]!='\0'){ //統(tǒng)計(jì)字符串中各字符存入S.ch中</p><p>  if(S.ch[j]==s[i]){ </p><p><b>  j=1;</b></p><p><b

37、>  i++;</b></p><p><b>  continue;</b></p><p>  }else j++;</p><p><b>  }</b></p><p>  S.ch[k]=s[i];</p><p><b>  k++;&

38、lt;/b></p><p><b>  i++;</b></p><p><b>  }</b></p><p>  S.ch[k]='\0';</p><p><b>  i=1;</b></p><p>  while(S.c

39、h[i]!='\0') </p><p><b>  i++;</b></p><p>  S.in[0]=i-1; </p><p>  for(i=1;S.ch[i]!='\0';){

40、 //統(tǒng)計(jì)字符串中各字符的個(gè)數(shù)</p><p>  for(j=0;s[j]!='\0';){</p><p>  if(S.ch[i]==s[j]){</p><p>  S.in[i]++;</p><p><b>  }</b></p><p><b> 

41、 j++;</b></p><p><b>  }</b></p><p><b>  i++;</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  //選擇par

42、ent=0且權(quán)值較小的兩個(gè)HTnode</p><p>  void select(HuffmanTree H,int j,int a[]){</p><p>  a[1]=a[2]=0;</p><p>  H.HTN[0].weight=1000;</p><p>  for(int i=1;i<=j;i++){</p>

43、<p>  if(H.HTN[i].parent==0){ //parent為0,則為未插入樹(shù)的結(jié)點(diǎn)</p><p>  if(H.HTN[i].weight<H.HTN[a[1]].weight){</p><p>  a[2]=a[1];</p><p><b>  a[1]=i;</b></

44、p><p><b>  }</b></p><p>  else if(H.HTN[i].weight<H.HTN[a[2]].weight){</p><p><b>  a[2]=i;</b></p><p><b>  }</b></p><p>

45、;<b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  //創(chuàng)建赫夫曼樹(shù)</b></p><p>  void creat_HuffmanTree(HuffmanTree &am

46、p;H){</p><p>  int i=H.length;</p><p>  int node[3];</p><p>  node[1]=i;node[2]=i;</p><p>  HTNode h1,h2;</p><p>  h1.weight=h2.weight=H.HTN[0].weight;<

47、/p><p>  for(int k=i+1;k<=H.size;k++){</p><p>  select(H,k-1,node); </p><p>  //選擇出兩個(gè)權(quán)值較小的兩個(gè)結(jié)點(diǎn),node存有兩個(gè)結(jié)點(diǎn)的值</p><p>  H.HTN[node[1]].parent=k; //構(gòu)造

48、出父親結(jié)點(diǎn)</p><p>  H.HTN[node[2]].parent=k;</p><p>  H.HTN[k].lchild=node[1];</p><p>  H.HTN[k].rchild=node[2];</p><p>  H.HTN[k].weight=H.HTN[node[1]].weight+H.HTN[node[2]

49、].weight;</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  //赫夫曼編碼</b></p><p>  void creat_HTCode(HuffmanTree H,Weight S){ </p>

50、;<p>  int i,j,n,k=25;</p><p>  for(i=0;i<30;i++) //Code_N用于計(jì)數(shù),初始化為0,為計(jì)數(shù)準(zhǔn)備</p><p>  Code_N[i]=0;</p><p>  for(i=1;i<=H.length;i++){

51、 //對(duì)每個(gè)字符進(jìn)行編碼</p><p>  k=25; //編碼不會(huì)超過(guò)25個(gè)字符</p><p>  //將各個(gè)字符編碼存入到Code中</p><p>  for(j=i,n=H.HTN[i].parent;j!=0;j=n,n=H.HTN[n].parent){ </p>

52、<p>  if(H.HTN[n].lchild==j){ </p><p>  Code[i][k--]='0';</p><p>  Code_N[i]++;</p><p><b>  }else{</b></p><p>  Code[i][k--]='1

53、9;;</p><p>  Code_N[i]++;</p><p><b>  }</b></p><p>  if(H.HTN[n].parent==0)</p><p><b>  break;</b></p><p><b>  }</b><

54、;/p><p><b>  }</b></p><p>  for(i=1;i<=H.length;i++) //循環(huán)輸出各個(gè)字符的編碼</p><p><b>  {</b></p><p>  printf("%c編碼為:",S

55、.ch[i]);</p><p>  for(k=25-Code_N[i]+1;k<=25;k++){</p><p>  printf("%c",Code[i][k]);</p><p><b>  }</b></p><p>  printf("\n");</p&g

56、t;<p><b>  }</b></p><p><b>  }</b></p><p><b>  //赫夫曼解碼</b></p><p>  void explain_HTCode(HuffmanTree H,Weight S){</p><p>  cha

57、r a[50],b[30];</p><p>  int n=0,i,j,l=0,k=0;</p><p>  printf("請(qǐng)輸入需要解碼的字符串(0—49例子:01010)\n");</p><p>  gets(a); </p><p>  while(a[

58、n]!='\0')</p><p><b>  n++;</b></p><p>  for(j=H.size,i=0;i<n;){ //結(jié)束控制為01字符個(gè)數(shù)的限制</p><p>  j=H.size; </p><p>  while(H.

59、HTN[j].lchild!=0&&H.HTN[j].rchild!=0&&a[i]!='\0'){</p><p>  if(a[i]=='0'){ </p><p>  j=H.HTN[j].lchild; i++;</p><p><b>  }</b></p

60、><p><b>  else{</b></p><p>  j=H.HTN[j].rchild; i++;</p><p><b>  }</b></p><p><b>  }</b></p><p>  if(j<=H.length){

61、 //控制當(dāng)剩余一部分01卻無(wú)法解碼</p><p>  b[l++]=S.ch[j]; //將對(duì)應(yīng)解碼的字符存放到b中用于輸出</p><p>  k=i; //記錄無(wú)法解碼01的個(gè)數(shù)用于輸出</p><p><b>  }</b></p><p

62、>  if(a[i]=='\0') </p><p><b>  break;</b></p><p><b>  }</b></p><p>  for(i=0;i<k;i++)</p><p>  printf("%c",a[i])

63、;</p><p>  printf("序列解碼后代碼為:");</p><p>  for(i=0;i<l;i++)</p><p>  printf("%c",b[i]);</p><p>  printf("\n無(wú)法解碼序列為:");</p><p&g

64、t;  for(i=k;i<n;i++)</p><p>  printf("%c",a[i]);</p><p><b>  }</b></p><p>  /*對(duì)指定文件進(jìn)行加密*/</p><p>  void encryptFile(Weight S){</p><p

65、>  FILE *fp1,*fp2;</p><p><b>  char ch;</b></p><p>  int k=25,i;</p><p>  char ming[]="D:\\",wen[20];</p><p>  char fileName[]="";<

66、;/p><p>  printf("\n請(qǐng)輸入讀取的文件的名稱(chēng)(例:outfile1.txt): ");</p><p><b>  do</b></p><p><b>  {</b></p><p>  scanf("%s",wen);</p>

67、<p>  if(strlen(wen)>20)</p><p>  printf("文件字符過(guò)長(zhǎng),(0~20)");</p><p>  }while(strlen(wen)>20);</p><p>  strcat(ming,wen);</p><p>  strcpy(fileName,min

68、g);</p><p>  if((fp1=fopen(ming,"r"))==NULL){ //打開(kāi)方式為讀取方式</p><p>  printf("%s文件無(wú)法打開(kāi)!",fileName);</p><p><b>  exit(1);</b><

69、/p><p><b>  }</b></p><p>  if((fp2=fopen("D:\\outFile.txt","w+"))==NULL){ //打開(kāi)方式為寫(xiě)入方式</p><p>  printf("D:\\outFile.txt%s文件無(wú)法打開(kāi)!");</p>

70、<p><b>  exit(1);</b></p><p><b>  }</b></p><p>  while((ch=fgetc(fp1))!=EOF){</p><p>  for(i=1;i<=S.in[0];i++){</p><p>  if(ch==S.ch[i

71、]){</p><p>  for(k=25-Code_N[i]+1;k<=25;k++){ //原理同赫夫曼編碼</p><p>  printf("%c",Code[i][k]);</p><p>  fputc(Code[i][k],fp2);</p><p><b>  }</b>

72、;</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  fclose(fp1); </p><p>  fclose(fp2);

73、 //關(guān)閉文件,對(duì)文件進(jìn)行保存</p><p>  fp1=fopen(fileName,"w"); //打開(kāi)方式為寫(xiě)入方式</p><p>  fp2=fopen("D:\\outFile.txt","r");

74、//打開(kāi)方式為讀取方式</p><p>  while((ch=getc(fp2))!=EOF){</p><p>  fputc(ch,fp1);</p><p><b>  }</b></p><p>  fclose(fp1); </p><p>  fclose(fp2); //

75、關(guān)閉文件</p><p><b>  }</b></p><p>  /*對(duì)指定文件進(jìn)行解密*/</p><p>  void deencryptFile(HuffmanTree H,Weight S){</p><p>  FILE *fp1,*fp2;</p><p><b>  c

76、har ch;</b></p><p>  char ming[]="D:\\",wen[20]; </p><p>  char fileName[]="";</p><p><b>  int i;</b></p><p>  printf("\n請(qǐng)輸入讀

77、取的文件的名稱(chēng)(例:outfile1.txt): ");</p><p><b>  do</b></p><p><b>  {</b></p><p>  scanf("%s",wen);</p><p>  if(strlen(wen)>20)</p&

78、gt;<p>  printf("文件字符過(guò)長(zhǎng),(0~20)");</p><p>  }while(strlen(wen)>20);</p><p>  strcat(ming,wen);</p><p>  strcpy(fileName,wen);</p><p>  if((fp1=fopen(

79、ming,"r"))==NULL){ //打開(kāi)方式為讀取方式</p><p>  printf("%s文件無(wú)法打開(kāi)!",ming);</p><p><b>  exit(1);</b></p><p><b>  }</b></

80、p><p>  if((fp2=fopen("D:\\outFile.txt","w+"))==NULL){ //打開(kāi)方式為寫(xiě)入方式</p><p>  printf("D:\\outFile.txt%s文件無(wú)法打開(kāi)!");</p><p><b>  exit(1);</b><

81、/p><p><b>  }</b></p><p>  ch=getc(fp1);</p><p>  while(ch!=EOF){ //原理同赫夫曼解碼</p><p><b>  i=H.size;&l

82、t;/b></p><p>  while(H.HTN[i].lchild!=0&&H.HTN[i].rchild!=0&&ch!=EOF){</p><p>  if(ch=='0'){</p><p>  i=H.HTN[i].lchild; ch=getc(fp1);</p><p>

83、;<b>  }</b></p><p><b>  else{</b></p><p>  i=H.HTN[i].rchild; ch=getc(fp1);</p><p><b>  }</b></p><p><b>  }</b></p&g

84、t;<p>  if(i<=H.length){</p><p>  printf("%c",S.ch[i]);</p><p>  fputc(S.ch[i],fp2);</p><p><b>  }</b></p><p>  if(ch==EOF)</p>&

85、lt;p><b>  break;</b></p><p><b>  }</b></p><p>  fclose(fp1); </p><p>  fclose(fp2); //關(guān)閉文件,對(duì)文件進(jìn)行保存</p>

86、;<p>  fp1=fopen(fileName,"w"); //打開(kāi)方式為寫(xiě)入方式</p><p>  fp2=fopen("D:\\outFile.txt","r"); //打開(kāi)方式為讀取方式</p><p>  while((ch=getc(fp2

87、))!=EOF){</p><p>  fputc(ch,fp1);</p><p><b>  }</b></p><p>  fclose(fp1); </p><p>  fclose(fp2); //關(guān)閉文件</p><p><b>  }</b></

88、p><p>  /*用于讀出文件中所儲(chǔ)存的全部信息*/</p><p>  void my_readFile(){</p><p><b>  FILE *fp;</b></p><p><b>  char ch; </b></p><p>  char ming[]=&quo

89、t;D:\\",wen[20]; </p><p>  printf("\n請(qǐng)輸入讀取的文件的名稱(chēng)(例:outfile1.txt): ");</p><p><b>  do</b></p><p><b>  {</b></p><p>  scanf("%

90、s",wen);</p><p>  if(strlen(wen)>20)</p><p>  printf("文件字符過(guò)長(zhǎng),(0~20)");</p><p>  }while(strlen(wen)>20);</p><p>  strcat(ming,wen);

91、 //將路徑和文件名稱(chēng)連接形成一個(gè)字符串</p><p>  if((fp=fopen(ming,"r"))==NULL){ //打開(kāi)方式為追加方式</p><p>  printf("%s文件無(wú)法打開(kāi)!",ming);</p><p><b>  exit(

92、1);</b></p><p><b>  }</b></p><p>  printf("文件內(nèi)容為:\n");</p><p>  while((ch=fgetc(fp))!=EOF)</p><p>  fputc(ch,stdout);</p><p>  

93、fclose(fp);</p><p><b>  }</b></p><p><b>  五 調(diào)試分析</b></p><p>  1、程序問(wèn)題解決及優(yōu)化</p><p>  1、核心問(wèn)題是創(chuàng)建赫夫曼樹(shù)并進(jìn)行編碼,但是在編碼問(wèn)題中出現(xiàn)了問(wèn)題,由于01編碼的長(zhǎng)度無(wú)法確定,我現(xiàn)在用的方法是用數(shù)組存放

94、,用計(jì)數(shù)來(lái)控制數(shù)組輸出,這樣會(huì)使空間浪費(fèi),改進(jìn)的想法是用指針來(lái)存儲(chǔ),這樣就可以節(jié)省空間,鑒于空間的使用和實(shí)現(xiàn)復(fù)雜程度就使用了數(shù)組存放。</p><p>  2、文件加密和解密部分,一開(kāi)始是使用讀取文件的內(nèi)容加密后保存到另一個(gè)文件中,但是對(duì)文件加密,應(yīng)該更好的是對(duì)加密文件本身加密。所以使用過(guò)渡文件即臨時(shí)文件,將要加密文件加密后內(nèi)容存入到這個(gè)臨時(shí)文件中,結(jié)束后再將臨時(shí)文件內(nèi)容轉(zhuǎn)存到要加密的文件。這樣就真正完成了對(duì)指定

95、文件本身的加密或者解密。</p><p>  3、對(duì)文件的操作,此程序主要是為了實(shí)現(xiàn)赫夫曼編碼及其應(yīng)用,只是把文件都默認(rèn)放到了D盤(pán)符下,可以加以改進(jìn)使用戶(hù)選擇盤(pán)符等,增加靈活性。</p><p><b>  六 測(cè)試結(jié)果</b></p><p><b>  1、屏幕輸出</b></p><p>&

96、lt;b>  1、輸出菜單顯示</b></p><p>  2、順序輸入帶有*號(hào)0、2、3:輸出字符赫夫曼編碼顯示</p><p>  3、輸入5 :輸入文件名稱(chēng)得到文件加密結(jié)果</p><p>  4、輸入6 :輸入解密文件名稱(chēng)得到解密結(jié)果</p><p>  5、輸入7:輸入文件名稱(chēng)查看文件內(nèi)容</p>&

97、lt;p><b>  2、文件加密效果</b></p><p>  經(jīng)過(guò)對(duì)比文件加密和解密后的內(nèi)容一致,文件加密成功。</p><p><b>  七 用戶(hù)使用說(shuō)明</b></p><p>  1、運(yùn)行環(huán)境及用戶(hù)操作說(shuō)明</p><p>  1、源代碼可在VC等編譯器下連接編譯運(yùn)行,huff

98、man.exe運(yùn)行環(huán)境要求低。</p><p><b>  下面是菜單頁(yè)面:</b></p><p>  2、運(yùn)行程序首先順序輸入帶有*號(hào)項(xiàng)0、2、3進(jìn)行赫夫曼編碼,然后就可以進(jìn)行4、赫夫曼解碼5、文件加密6、文件解密功能。</p><p>  3、在有關(guān)文件操作的選項(xiàng)中,都是輸入文件的名稱(chēng)包括文件的后綴。在六中結(jié)果演示中操作說(shuō)明已經(jīng)詳細(xì),并且

99、屏幕的提示輸出可以引導(dǎo)用戶(hù)簡(jiǎn)單操作此程序。</p><p><b>  八 課程設(shè)計(jì)總結(jié)</b></p><p><b>  1、學(xué)習(xí)心得</b></p><p>  1、通過(guò)這個(gè)課程設(shè)計(jì)可以知道,有關(guān)于利用赫夫曼樹(shù)求字符串的最優(yōu)編碼的基本方法有兩類(lèi),而在此程序中用到的是從葉子節(jié)點(diǎn)到根節(jié)點(diǎn)求編碼的方法,還有一種是從根到葉

100、子節(jié)點(diǎn)的方法,不過(guò)相對(duì)而言,這里運(yùn)用到的程序?qū)崿F(xiàn)代碼更容易讓人理解。</p><p>  2、通過(guò)此次程序編寫(xiě),對(duì)算法的空間和時(shí)間,還有實(shí)現(xiàn)難度上有了自己的理解,通過(guò)數(shù)據(jù)結(jié)構(gòu)的選取可以使得空間得到有效利用,并且應(yīng)該考慮到效率問(wèn)題,現(xiàn)在小程序可能體現(xiàn)不出什么問(wèn)題,并且這次對(duì)文件的操作又熟悉了,之前淺學(xué)了下數(shù)據(jù)庫(kù),通過(guò)學(xué)習(xí)的深入和對(duì)比,明白了在學(xué)習(xí)中要勤于思考,對(duì)知識(shí)間的聯(lián)系要善于發(fā)現(xiàn)和總結(jié),從而真正掌握。</

101、p><p>  3、在這個(gè)實(shí)驗(yàn)過(guò)程中實(shí)現(xiàn)赫夫曼編碼的過(guò)程中,對(duì)赫夫曼編碼的應(yīng)用自己有了更深入一步的了解。在這里只是用這個(gè)編碼用作加密作用。赫夫曼編碼可以起到壓縮的作用,要是把編碼后的字符串看做8bits為一字節(jié)的話(huà),在字符串中字符的頻率都較高的情況下,加密后的編碼轉(zhuǎn)換為8bits為一字節(jié)的話(huà),就起到了壓縮文件的內(nèi)容,要是根據(jù)文件確定字符的權(quán)值,再把權(quán)值信息放到另一個(gè)文件中,這樣既起到了壓縮文件作用又起到了加密文件的內(nèi)

102、容,要是不知道權(quán)值信息是無(wú)法解壓的。經(jīng)過(guò)查詢(xún)資料,了解到赫夫曼編碼是一種統(tǒng)計(jì)編碼。屬于無(wú)損壓縮編碼等等信息。所以實(shí)驗(yàn)中應(yīng)該不斷學(xué)習(xí)新的知識(shí)并且應(yīng)該用于實(shí)踐,這樣收獲會(huì)更多。</p><p><b>  源代碼: </b></p><p>  注: 編輯器:vc 6.0 </p><p>  #include <stdio.h><

103、;/p><p>  #include <stdlib.h></p><p>  #include <iostream.h></p><p>  #include <string.h></p><p>  typedef struct{</p><p>  int weight;</

104、p><p>  int parent,lchild,rchild;</p><p>  }HTNode; //構(gòu)造赫夫曼樹(shù)結(jié)點(diǎn)的結(jié)構(gòu)體</p><p>  typedef struct{</p><p>  HTNode *HTN; //存儲(chǔ)編碼的各個(gè)字符</p><p>  int l

105、ength; //需編碼字符個(gè)數(shù)</p><p>  int size; //赫夫曼編碼總?cè)萘?lt;/p><p>  }HuffmanTree; //構(gòu)造赫夫曼樹(shù)的結(jié)構(gòu)體</p><p>  typedef struct{</p><p>  char *ch; //存放需要編碼的原始字碼<

106、;/p><p>  int *in; //存放各個(gè)字碼的權(quán)值</p><p><b>  }Weight; </b></p><p>  char Code[27][26]; //存放各個(gè)字符的赫夫曼編碼01</p><p>  int Code_N[30]; //存放各個(gè)字符對(duì)應(yīng)編碼01的

107、個(gè)數(shù),用于輸出控制</p><p><b>  //輸出菜單列表</b></p><p>  void showMenu();</p><p>  //對(duì)赫夫曼樹(shù)結(jié)構(gòu)初始化</p><p>  void Init_HuffmanTree(HuffmanTree &H,Weight S);</p>&

108、lt;p>  //對(duì)編碼個(gè)數(shù)和權(quán)值的結(jié)構(gòu)初始化</p><p>  void Init_Weight(Weight &S,int msize,int msize1);</p><p>  //求出輸入字符串各個(gè)字符的權(quán)值</p><p>  void WeightNumber(Weight &S);</p><p>  

109、//選擇parent=0且權(quán)值較小的兩個(gè)HTnode</p><p>  void select(HuffmanTree H,int j,int a[]);</p><p><b>  //創(chuàng)建赫夫曼樹(shù)</b></p><p>  void creat_HuffmanTree(HuffmanTree &H);</p>&l

110、t;p><b>  //赫夫曼編碼</b></p><p>  void creat_HTCode(HuffmanTree H,Weight S);</p><p><b>  //赫夫曼解碼</b></p><p>  void explain_HTCode(HuffmanTree H,Weight S);<

111、/p><p>  /*對(duì)指定文件進(jìn)行加密*/</p><p>  void encryptFile(Weight S);</p><p>  /*對(duì)指定文件進(jìn)行解密*/</p><p>  void deencryptFile(HuffmanTree H,Weight S);</p><p>  /*用于讀出文件中所儲(chǔ)存的

112、全部信息*/</p><p>  void my_readFile();</p><p>  //主函數(shù)實(shí)現(xiàn)赫夫曼樹(shù)</p><p>  void main()</p><p><b>  {</b></p><p>  HuffmanTree h;</p><p><

113、;b>  Weight s;</b></p><p>  Init_Weight(s,50,50);</p><p>  char choose='\0',yes_no='\0',ch;</p><p><b>  do</b></p><p><b>  {&

114、lt;/b></p><p>  showMenu();</p><p>  printf(" 選擇: ");</p><p>  cin>>choose;</p><p>  switch(choos

115、e)</p><p><b>  {</b></p><p>  case'1': {WeightNumber(s);</p><p><b>  }break;</b></p><p>  case'2': {Init_HuffmanTree(h,s);</p

116、><p>  creat_HuffmanTree(h);</p><p><b>  }break;</b></p><p>  case'3': {creat_HTCode(h,s);</p><p><b>  }break;</b></p><p>  ca

117、se'4': {explain_HTCode(h,s);</p><p><b>  }break;</b></p><p>  case'5': {encryptFile(s);</p><p><b>  }break;</b></p><p>  case

118、9;6': {deencryptFile(h,s);</p><p><b>  }break;</b></p><p>  case'7':{my_readFile();</p><p><b>  }break;</b></p><p>  case'8'

119、: {exit(0);</p><p><b>  }break;</b></p><p>  case'0': { </p><p>  //對(duì)26個(gè)字符設(shè)置給定的權(quán)值</p><p>  s.ch[1]='e';s.ch[2]='a';s.ch[3]='r&#

120、39;;s.ch[4]='i';s.ch[5]='o';</p><p>  s.ch[6]='t';s.ch[7]='n';s.ch[8]='s';s.ch[9]='l';s.ch[10]='c';</p><p>  s.ch[11]='u';s.ch[12]

121、='d';s.ch[13]='p';s.ch[14]='m';s.ch[15]='h';</p><p>  s.ch[16]='g';s.ch[17]='b';s.ch[18]='f';s.ch[19]='y';s.ch[20]='w';</p><

122、p>  s.ch[21]='k';s.ch[22]='v';s.ch[23]='x';s.ch[24]='z';s.ch[25]='j';</p><p>  s.ch[26]='q';</p><p>  s.in[1]=57;s.in[2]=43;s.in[3]=39;s.in[4]=

123、38;s.in[5]=37;</p><p>  s.in[6]=35;s.in[7]=34;s.in[8]=29;s.in[9]=28;s.in[10]=23;</p><p>  s.in[11]=19;s.in[12]=17;s.in[13]=16;s.in[14]=15;s.in[15]=15;</p><p>  s.in[16]=13;s.in[17]=

124、11;s.in[18]=9;s.in[19]=9;s.in[20]=7;</p><p>  s.in[21]=6;s.in[22]=5;s.in[23]=1;s.in[24]=1;s.in[25]=1;</p><p>  s.in[26]=1;s.in[0]=26; </p><p><b

125、>  FILE *fp;</b></p><p>  if((fp=fopen("original.txt","w"))==NULL){ //打開(kāi)文件</p><p>  printf("文件不能打開(kāi)");</p><p><b>  exit(1);<

126、/b></p><p><b>  }</b></p><p>  for(int i=1;i<=26;i++){</p><p>  fprintf(fp,"%c %d ",s.ch[i],s.in[i]);</p><p><b>  }</b></p>

127、;<p>  fclose(fp);</p><p><b>  }break;</b></p><p>  cout<<"\n\n\n\t\t\t確定退出(Y||N)";</p><p><b>  cin>>ch;</b></p><p>

128、;  if(ch=='Y'||ch=='y')</p><p><b>  exit(0);</b></p><p>  default:printf("\n %c 沒(méi)有此選項(xiàng)! 錯(cuò)誤! \n ",choose);</p><p><b>  }</b></p

129、><p>  printf("\n\n 繼續(xù)? 回到主菜單 (Y&y||N&n) \t請(qǐng)選擇:");</p><p><b>  do</b></p><p><b>  {</b></p><p>  cin>>yes_no;</p>

130、<p>  } while(yes_no!='Y'&&yes_no!='y'&&yes_no!='N'&&yes_no!='n');</p><p>  } while(yes_no=='Y'||yes_no=='y');</p><p>

131、;<b>  exit(0);</b></p><p><b>  }</b></p><p><b>  //輸出菜單列表</b></p><p>  void showMenu(){</p><p>  cout<<"\t\t-------------

132、-----文件加密------------------"<<"\n"</p><p>  <<"\t\t\t* 0、根據(jù)給定的字符權(quán)值"<<"\n"</p><p>  <<"\t\t\t 1、輸入需要編碼的字符串"<<"\n&q

133、uot;</p><p>  <<"\t\t\t* 2、創(chuàng)建赫夫曼樹(shù)"<<"\n"</p><p>  <<"\t\t\t* 3、對(duì)各字符進(jìn)行赫夫曼編碼"<<"\n"</p><p>  <<"\t\t\t 4、輸入

134、01串進(jìn)行赫夫曼解碼"<<"\n"</p><p>  <<"\t\t\t* 5、對(duì)文件進(jìn)行加密"<<"\n"</p><p>  <<"\t\t\t* 6、對(duì)文件進(jìn)行解密"<<"\n"</p><p&

135、gt;  <<"\t\t\t 7、讀取文件內(nèi)容"<<"\n"</p><p>  <<"\t\t\t 8、退出"<<"\n"</p><p>  <<"\t\t---------------------------------------

136、------"<<endl;</p><p><b>  }</b></p><p>  //對(duì)赫夫曼樹(shù)結(jié)構(gòu)初始化</p><p>  void Init_HuffmanTree(HuffmanTree &H,Weight S){</p><p>  H.HTN=new HTNode[S.i

137、n[0]*2-1];</p><p>  for(int i=1;i<=S.in[0]*2-1;i++){ //將H.HTN[i]權(quán)值、父親節(jié)點(diǎn)、左右孩子都設(shè)置為0</p><p>  H.HTN[i].weight=0;</p><p>  H.HTN[i].parent=0;</p><p>  H.HTN[i].lchild=

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論