?? 4.cpp
字號:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 1
#define NULL 0
#define TURE 1
#define FALSE 0
#define EOF (-1)
int S1=0;
int i;
int S2=0;
char ch[27];
typedef struct HT
{
char ch;
int num;
int weight;
int parent,lchild,rchild;
} HTNode,*HuffmanTree;//定義哈夫曼樹結點
typedef char* *Huffmancode;
//-------------——————--------------------功能函數列表-----------------------------------------//
int Select(HuffmanTree HT,int n);
int Initialization (HuffmanTree HT,int n);
int Encoding (HuffmanTree HT,int n);
int Decoding (HuffmanTree HT,int n);
int Print ();
int TreePrinting (HuffmanTree HT,int n);
//-----------——————---------------------主函數----------------————-------------------------//
int main ()
{
int m,n=0;
char ch;
HuffmanTree HT;//定義HT為哈夫曼樹
printf("***********************歡迎使用本系統(開發人 厲啟鵬)*************************\n");
printf(" A 初始化 B 編碼 C 譯碼 D 印碼文件 E 印哈夫曼樹 F 退出\n");
while(1)
{
while(1)
{
fflush(stdin);
printf("\n請選擇您需要的操作:");
scanf("%c",&ch);
fflush(stdin);
if(ch>=65&&ch<=70) break;
}
switch(ch)
{
case'A':
printf("請輸入字符個數:");
scanf("%d",&n);//輸入需要編碼的字符的個數
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//為哈夫曼樹開辟存儲空間
Initialization (HT,n);
break;
case'B':
Encoding(HT,n);
break;
case'C':
Decoding(HT,n);
break;
case'D':
Print ();
break;
case'E':
TreePrinting(HT,n);
break;
case'F':
return 0;
default: break;
}
}
}
//-----------——————---------------------主函數----------------————-------------------------//
int Initialization (HuffmanTree HT,int n)
{ //初始化哈夫曼樹函數
int m,i;
FILE *out1;
//將字符存入該數組
m=2*n-1;
printf("請輸入空格的頻度:");
scanf("%d",&HT[1].weight);
HT[1].num=1;
HT[1].ch=NULL;
HT[1].parent=NULL;//將每個節點的指針均初始化為空
HT[1].lchild=NULL;
HT[1].rchild=NULL;
for(i=2;i<=n;i++)
{
printf("請輸入第%d個字符:",i);
scanf("%s",&HT[i].ch);
printf("請輸入該字符的頻度:");
scanf("%d",&HT[i].weight);
HT[i].num=i;
HT[i].parent=NULL;//將每個節點的指針均初始化為空
HT[i].lchild=NULL;
HT[i].rchild=NULL;
}
for(i=n+1;i<=m;++i)
{
Select(HT,i-1);
//在HT[1...n]中選擇parent為0,且weight最小的兩個節點,其序號分別是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;
HT[i].parent=NULL;
HT[i].num=i;
HT[i].ch=' ';
}
//printf("%s %s %s %s %s",HT[i].num,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
if((out1=fopen("hfmTree.txt","w"))==NULL)//建立文件hfmTree.txt以存儲哈夫曼樹
{
printf("文件錯誤\n !");
}
fputs("fuhao num weight parent lchild rchild \n",out1);
for(i=1;i<=m;i++)//將哈夫曼樹存入hfmTree.txt文件
{
fprintf(out1,"%-10c%-10d%-10d%-10d%-10d%-10d\n",HT[i].ch,HT[i].num,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
}
fclose(out1);
printf("哈夫曼樹已構造完成,并已存入hfmTree.txt文件!\n");
return OK;
}
int Encoding(HuffmanTree HT,int n)
{
int i,start,c,f;
char ch,infile[20];
FILE *in,*out2,*out3;
if(n==0) //未建立哈夫曼樹
{
printf("請先建立哈夫曼樹!\n");
return NULL;
}
Huffmancode HC=(Huffmancode)malloc((n+1)*sizeof(char*));//分配n個字符編碼的頭指針向量
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';
else cd[--start]='1';
}
HC[i]=(char*)malloc((n-start)*sizeof(char));//為第i個字符編碼分配空間
strcpy(HC[i],&cd[start]);//從cd復制編碼(串)到HC
}
free(cd);//釋放工作空間
for(i=1;i<=n;i++) printf("%s\n",HC[i]);
if((out3=fopen("CodeFile.txt","w"))==NULL)//建立CodeFile.txt文件以存儲對正文的編碼
{
printf("文件錯誤!\n ");
}
if((in=fopen("ToBeTran.txt","r"))==NULL)//打開需要編碼的文件ToBeTran.txt
{
printf("\n 打不開此ToBeTran.txt文件!");
}
ch=fgetc(in);
while(ch!=EOF)//對正文中的逐個字符進行編碼
{
putchar(ch);
for(i=1;i<=n;++i)
{
if(ch==HT[i].ch)
{
fprintf(out3,"%s",HC[i]);//將編碼結果寫進CodeFile.txt文件
}
else continue;
}
ch=fgetc(in);
}
fclose(out3);//關閉文件
printf("編碼已完成并存入CodeFile.txt文件!");
return OK;
}
int Decoding(HuffmanTree HT,int n)
{
int c,f;
char infile[20],ch;
FILE *in,*out;
if(n==0) //未建立哈夫曼樹
{
printf("請先建立哈夫曼樹!\n");
return NULL;
}
if((out=fopen("TextFile.txt","w"))==NULL)//建立文件以儲存編碼
{
printf("\n 建立文件失敗!");
}
printf("請輸入需要譯碼的文件名(默認文件為CodeFile.txt):");
scanf("%s",infile);
if((in=fopen(infile,"r"))==NULL)
{
printf("\n請檢查您是否建樹或編碼!");
return NULL;
}
ch=fgetc(in);
c=2*n-1;
f=c;
while(ch!=EOF)//對正文中的逐個字符進行譯碼
{
if(ch=='0')
{
f=HT[c].lchild;
c=f;
if(HT[f].lchild==0 && HT[f].rchild==0)
{
fprintf(out,"%c",HT[f].ch);
c=2*n-1;
f=c;
}
}
if(ch=='1')
{
f=HT[c].rchild;
c=f;
if(HT[f].lchild==0 && HT[f].rchild==0)
{
fprintf(out,"%c",HT[f].ch);
c=2*n-1;
f=c;
}
}
ch=fgetc(in);
}
fclose(out);
printf("譯碼已完成并存入TextFile.txt文件!");
return OK;
}
int Print()
{
char infile[20],ch,i=0;
FILE *in,*out;
printf("請輸入存放編碼的文件名(默認為CodeFile.txt):");
scanf("%s",infile);
if((in=fopen(infile,"r"))==NULL)
{
printf("\n 此文件不存在,請先建立!");
return NULL;
}
if((out=fopen("CodePrin.txt","w"))==NULL)
{
printf("\n 建立文件失敗!");
}
ch=fgetc(in);
while(ch!=EOF)
{
++i;
putchar(ch);
fprintf(out,"%c",ch);
if(i==50)
{
printf("\n");
fputs("\n",out);
i=0;
}
ch=fgetc(in);
}
fclose(out);
fclose(in);
return OK;
}
int TreePrinting (HuffmanTree HT,int n)
{
FILE *out;
int m;
m=2*n-1;
if(n==0) //未建立哈夫曼樹
{
printf("請先建立哈夫曼樹!\n");
return NULL;
}
if((out=fopen("TreePrint.txt","w"))==NULL)//建立文件hfmTree.txt以存儲哈夫曼樹
{
printf("文件錯誤\n !");
}
printf("fuhao num weight parent lchild rchild \n");
fputs("fuhao num weight parent lchild rchild \n",out);
for(i=1;i<=m;i++)//將哈夫曼樹存入hfmTree.txt文件
{
fprintf(out,"%-10c%-10d%-10d%-10d%-10d%-10d\n",HT[i].ch,HT[i].num,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
printf("%-10c%-10d%-10d%-10d%-10d%-10d\n",HT[i].ch,HT[i].num,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
}
fclose(out);
return OK;
}
int Select(HuffmanTree HT,int n)
{
int i,j,min1,min2;
min1=32767;
min2=32767;
for(i=1;i<=n;i++)
{
if(HT[i].weight<min1 && HT[i].parent==NULL)
{
min1=HT[i].weight;
S1=i;
}
}
for(j=1;j<=n;j++)
{
if(HT[j].weight<min2 && HT[j].parent==NULL && j!=S1)
{
min2=HT[j].weight;
S2=j;
}
}
return OK;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -