Infiniti

   :: 首页  :: 新随笔  ::  ::  :: 管理
#include<bits/stdc++.h>
#define N  8
typedef struct hm
{
    char ch;
    char code[20];
} HuffM;
typedef struct s
{
    char ch;
    int frq;
} mytype;
typedef struct bt
{
    struct bt *lchild;
    mytype dt;
    struct bt *rchild;
} bitree;
int g_flag=0;
int Encoding(HuffM d[]);
int PreOrderPrint(bitree *HT,int cont);
void PrintCodeFile();
void PrintTextFile();
int Decoding(HuffM d[]);
int reaData(mytype d[])//载入数据
{
    FILE * fp;
    int i=0;
    fp=fopen("data.txt","r");
    if(NULL==fp)
    {
        return -1;
    }
    while(!feof(fp))
    {
        fscanf(fp,"%c",&(d[i].ch));
        fscanf(fp,"%d",&(d[i].frq));
        fseek(fp,2,SEEK_CUR);
        i++;
        if(i==N-2)
            break;
    }
    g_flag=1;
    fclose(fp);
    return 0;
}
int reaHFData(HuffM d[])//从hfmTree.txt文件读取数据
{
    FILE * fp;
    int i=0,td;
    char c,data[20];
    fp=fopen("hfmTree.txt","r");
    if(NULL==fp)
    {
        printf("打开哈夫曼编码数据文件出错。\n");
        return -1;
    }
    while(1)
    {
        fscanf(fp,"%c%d%s",&c,&td,data);
        if(feof(fp))
            break;
        d[i].ch=c;
        strcpy(d[i].code,data);
        i++;
        fseek(fp,2,SEEK_CUR);
    }
    g_flag=1;
    fclose(fp);
    return 0;
}
int printData(mytype d[]) //数据显示 字符 频度
{
    int i=0;
    if(g_flag<1)
    {
        printf("请先载入数据文件。\n");
        return 0;
    }
    for(; i<N-3; i++)
    {
        printf("%c\t%d\n",d[i].ch,d[i].frq);
    }
    return 0;
}
int printHFData(HuffM d[]) //显示哈夫曼树 字符 编码
{
    int i=0;
    if(g_flag<1)
    {
        printf("请先载入数据文件。\n");
        return 0;
    }
    for(; i<N-3; i++)
    {
        printf("%c\t%s\n",d[i].ch,d[i].code);
    }
    return 0;
}
int sort(mytype d[])//对数据频度大小排序 建哈夫曼树时调用
{
    int i,j;
    mytype temp;

    if(g_flag<1)
    {
        printf("请先载入数据文件。\n");
        return 0;
    }
    for(i=0; i<N-4; i++)
    {
        for(j=0; j<N-4-i; j++)
        {
            if(d[j].frq>d[j+1].frq)
            {
                temp=d[j];
                d[j]=d[j+1];
                d[j+1]=temp;
            }
        }
    }
}
int sortHMC(HuffM d[])//对哈夫曼树字符排序  译码文件时调用
{
    int i,j;
    HuffM temp;
    if(g_flag<1)
    {
        printf("请先载入数据文件。\n");
        return 0;
    }
    for(i=0; i<N-4; i++)
    {
        for(j=0; j<N-4-i; j++)
        {
            if(d[j].ch>d[j+1].ch)
            {
                temp=d[j];
                d[j]=d[j+1];
                d[j+1]=temp;
            }
        }
    }
}
int sort1(bitree* temp[N],int n)//对新的数据重新 频度大小排序 建树时调用
{
    int i,j;
    bitree* tmp;
    for(i=0; i<n-1; i++)
    {
        for(j=0; j<n-1-i; j++)
        {
            if(temp[N-3-n+j]->dt.frq>temp[N-3-n+j+1]->dt.frq)
            {
                tmp=temp[N-3-n+j];
                temp[N-3-n+j]=temp[N-3-n+j+1];
                temp[N-3-n+j+1]=tmp;
            }
        }
    }
}
bitree * createbt(mytype d[])//建哈夫曼树
{
    bitree* head=NULL;
    bitree* temp[N]= {NULL};
    int i=0;
    if(g_flag<1)
    {
        printf("请先载入数据文件。\n");
        return 0;
    }
    sort(d);
    while(i<N-3)
    {
        temp[i]=(bitree *)malloc(sizeof(bitree));
        temp[i]->dt=d[i];
        temp[i]->lchild=NULL;
        temp[i]->rchild=NULL;
        i++;
    }
    i=0;
    while(i<N-4)
    {
        head=(bitree *)malloc(sizeof(bitree));
        head->dt.ch='*';
        head->dt.frq=temp[i]->dt.frq + temp[i+1]->dt.frq;
        head->lchild=temp[i];
        head->rchild=temp[i+1];
        temp[i+1]=head;
        temp[i]=NULL;
        sort1(temp,N-i-4);
        i++;
    }
    g_flag = 11;
    return head;
}
bitree * destroybt(bitree * head)//销毁哈夫曼树,释放空间  递归调用
{
    bitree *temp;
    if(head==NULL)
        return NULL;
    temp=head;
    if(head->lchild)
        head->lchild=destroybt(temp->lchild);
    if(head->rchild)
        head->rchild=destroybt(temp->rchild);
    free(head);
    head=NULL;
    return NULL;
}
void HuffManCoding(bitree *BT, int len,FILE *fp)    //哈夫曼树编码  利用 static函数  并写入文件
{
    static int a[10];
    int i;
    if(g_flag<11)
    {
        printf("请先建立哈夫曼树。\n");
        return  ;
    }
    if(BT!=NULL)
    {
        if(BT->lchild==NULL&&BT->rchild==NULL)
        {
            fprintf(fp,"%c\t%d\t",BT->dt.ch,BT->dt.frq);
            for(i=0; i<len; i++)
                fprintf(fp,"%d",a[i]);
            fprintf(fp,"\n");
        }
        else
        {
            a[len]=0;
            HuffManCoding(BT->lchild, len+1,fp);
            a[len]=1;
            HuffManCoding(BT->rchild, len+1,fp);
        }
    }
}
int  menu()
{
    int n;
    printf("*****************************\n");
    printf("字符集和频度操作:\n");
    printf("\t1.载入数据文件。\n");
    printf("\t2.显示数据。\n");
    printf("\t3.排序。\n");
    printf("哈夫曼树操作:\n");
    printf("\t4.建立哈夫曼树。\n");
    printf("\t5.写入哈夫曼编码文件。\n");
    printf("\t6.显示哈夫曼编码文件。\n");
    printf("\t7.销毁哈夫曼树。\n");
    printf("哈夫曼编译码操作:\n");
    printf("\t8.载入哈夫曼编码。\n");
    printf("\t9.显示哈夫曼编码。\n");
    printf("\t10.编码ToBeTran文件.\n");
    printf("\t11.译码CodeFile文件.\n");
    printf("\t12.打印CodeFile文件.\n");
    printf("\t13.打印译码TextFile文件.\n");
    printf("\t14.打印哈夫曼树.\n");
    printf("\t15.退出\n");
    printf("*****************************\n");
    printf("请输入选择:");
    while(1)
    {
        scanf("%d",&n);
        if(n>0&&n<=15) break;
        printf("输入错误,请重输:");
    }
    system("cls");
    return n;
}
int printHuffManfile() //输出哈夫曼树  字符  频度 编码
{
    FILE * fp;
    char data[50],c;
    int d;
    fp=fopen("hfmTree.txt","r");
    if(NULL==fp)
    {
        printf("打开文件哈夫曼编码错误。\n");
        return -1;
    }
    while(1)
    {
        fscanf(fp,"%c%d%s",&c,&d,data);
        if(feof(fp))
            break;
        printf("%c\t%d\t%s\n",c,d,data);
        fseek(fp,2,SEEK_CUR);
    }
    fclose(fp);
}
main()
{
    mytype data[N]= {0};
    HuffM  hmdata[N]= {0};
    int flag;
    int choose,cont;
    FILE *fp;
    bitree *bthead=NULL;
    cont=0;
    g_flag=0;//刚开始时数据为空。
    while(1)
    {
        choose=menu();
        switch(choose)
        {
        case 1:
            flag=reaData(data);
            if(-1==flag)
            {
                printf("Open data.txt file error!\n");
                return 0;
            }
            break;
        case 2:
            printData(data);
            break;
        case 3:
            sort(data);
            break;
        case 4:
            bthead=createbt(data);
            break;
        case 5:
            fp=fopen("hfmTree.txt","w+");
            if(NULL==fp)
            {
                printf("写入哈夫曼编码错误!\n");
                return 0;
            }
            HuffManCoding(bthead,0,fp);
            g_flag=111;
            fclose(fp);
            break;
        case 6:
            printHuffManfile();
            break;
        case 7:
            if(g_flag<11)
            {
                printf("请先建立哈夫曼树。\n");
                break;
            }
            bthead=destroybt(bthead);
            g_flag=1;
            break;
        case 8:
            flag=reaHFData(hmdata);
            if(-1==flag)
            {
                printf("Open data.txt file error!\n");
                return 0;
            }
            sortHMC(hmdata);
            break;
        case 9:
            printHFData(hmdata);
            break;
        case 10:
            Encoding(hmdata);
            break;
        case 11:
            Decoding(hmdata);
            break;
        case 12:
            PrintCodeFile();
            break;
        case 13:
            PrintTextFile();
            break;
        case  14:
            PreOrderPrint(bthead,cont);
            break;
        case 15:
            destroybt(bthead);
            return 0;
            break;
        }
    }
}
int Encoding(HuffM d[])//编码
{
    FILE *fp,*pfc;
    char data[256]= {0},c;
    fp=fopen("ToBeTran.txt","r");
    pfc=fopen("CodeFile.txt","w");
    if(NULL==fp)
    {
        printf("打开文件ToBeTran.txt出错,编码未完成.\n");
        return -1;
    }
    if(NULL==pfc)
    {
        fclose(fp);
        printf("CodeFile.txt出错,编码未完成.\n");
        return -1;
    }
    while(1)
    {
        fread(&c,1,1,fp);
        if(c>='a'&&c<='z')
            c-=32;
        if(c>='A'&&c<='Z')
        {
            fprintf(pfc,"%s",d[c-'A'+1].code);
        }
        else if (c==' ')
            fprintf(pfc,"%s",d[0].code);
        else
            fprintf(pfc,"%c",c);
        if(feof(fp))
            break;
    }
    fclose(fp);
    fclose(pfc);
}
int Decoding(HuffM d[])//编码
{
    FILE *fp, *pfc;
    char data[20] = { 0 },c;
    int i;//, flag
    fp = fopen("ToBeTran.txt", "r");
    pfc = fopen("TextFile.txt", "w");
    if (NULL == fp)
    {
        printf("打开文件ToBeTran.txt出错,译码未完成.\n");
        return -1;
    }
    if (NULL == pfc)
    {
        fclose(fp);
        printf("TextFile.txt出错,译码未完成.\n");
        return -1;
    }
    while (1)
    {
        fread(&c, 1, 1, fp);
        if (c=='1'|| c=='0')
        {
            //	return  1;
            for(i=0; i<27; i++)
            {
                data[i]=c;
                while (strcmp(d[i].code,data)==0)
                    fprintf(pfc,"%c",d[i].ch);
            }
        }
        else
            fprintf(pfc,"%c",c);
        if (feof(fp))
            break;
    }
    fclose(fp);
    fclose(pfc);
    return  1;
}
void PrintCodeFile()
{
    FILE *fc;
    int flag;
    char ch;
    printf("打印编码后的文件:\n ");
    fc=fopen("CodeFile.txt", "r");
    if (NULL==fc)
    {
        printf("打印编码后的文件失败!! ");
        exit(0);
    }
    flag = 1;
    while (!feof(fc))
    {
        ch = fgetc(fc);
        if (ch == -1)
        {
            printf("结束打印\n");
        }
        else
        {
            printf("%c", ch);
            if (flag <= 49)
                flag++;
            else
            {
                flag = 1;
                printf("\n");
            }
        }
    }
    fclose(fc);
}
void PrintTextFile()
{
    FILE *fc;
    int flag;
    char ch;
    printf("打印译码后的文件:\n ");
    fc=fopen("TextFile.txt", "r");
    if (NULL==fc)
    {
        printf("打印译码后的文件失败!! ");
        exit(0);
    }
    flag = 1;
    while (!feof(fc))
    {
        ch = fgetc(fc);
        if (ch == -1)
        {
            printf("结束打印\n");
        }
        else
        {
            printf("%c", ch);
            if (flag <= 49)
                flag++;
            else
            {
                flag = 1;
                printf("\n");
            }
        }
    }
    fclose(fc);
}
int  PreOrderPrint(bitree *HT,int cont)
{
    int n = 2 * (N - 3) - 1, i;
    if(NULL!=HT)
    {
        for (i = 0; i<cont; i++)
            printf("   ");
        printf("%c%d\n",HT->dt.ch,HT->dt.frq);
        PreOrderPrint(HT->lchild, cont+1);
        PreOrderPrint(HT->rchild, cont+1);
    }
    return  1;
}

  

posted on 2019-06-27 08:46  自由缚  阅读(185)  评论(0编辑  收藏  举报