ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Huffman编码/译码问题

2022-01-17 23:01:38  阅读:148  来源: 互联网

标签:fp 编码 int root Tree else 译码 NULL Huffman


Huffman编码/译码

问题描述

利用哈夫曼编码进行信息通讯可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码;在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼码的编译码系统。

基本要求

一个完整的系统应具有以下功能:
(1) I:初始化(Initialization)。从终端读入字符集大小n,及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmtree中。
(2) C:编码(Coding)。利用已建好的哈夫曼树(如不在内存,则从文件hfmtree中读 入),对文件tobetrans中的正文进行编码,然后将结果存入codefile中。
(3) D:译码(Decoding)。利用已建好的哈夫曼树将文件codefile中的代码进行译 码,结果存入文件textfile中。
(4) P:印代码文件(Print)。将文件codefile以紧凑格式显示在终端上,每行50个代 码。同时将此字符形式的编码文件写入文件codeprint中。
(5) T:印哈夫曼树(Tree print)。将已在内存中的哈夫曼树以直观的方式 树或凹入表行式)显示在终端上,同时将此字符形式的哈夫曼树写入文件treeprint中。
测试数据:
用下表中给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的编码和译码: “THIS PROGRAM IS MY FAVORITE”.
字符集和频度的实际统计数据
实现提示
(1) 文件codefile的基类型可以设为子界型 bit=0…1。
(2) 用户界面可以设计为"菜单"方式: 显示上述功能符号,再加上"E",表示结束运行End,请用户键入一个选择功能符。此功能执行完毕后再显示此菜单,直至某次用户选择了"E"为止。
(3) 在程序的一次执行过程中,第一次执行I,D或C命令之后,哈符曼树已经在内存了,不必再读入。每次执行中不一定执行I命令,因为文件hfmtree可能早己建好。

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

typedef struct HT{
    int val;
    char word;
    bool bitt[30];
    struct HT *left, *right;
};

struct HT *Huffman_Tree[30], *roott;

bool Huff[30][30];
char Huffq[30][30];

int nn = 30, HuffLen[30];

void Build_Tree(int n, struct HT *root, int k) {
    struct HT *q = (struct HT*) malloc(sizeof(struct HT));
    q->left = NULL;
    q->right = NULL;
    q->val = 0;
    if (Huffq[n][k] == '\0') {
        if (n == 26) {
            root->word = ' ';
        }
        else {
            root->word = n + 'A';
        }
    }
    else if (Huffq[n][k] == '0') {
        if (root->left == NULL) {
            q->word = '*';
            root -> left = q;
            Build_Tree(n, q, k + 1);
        }
        else {
            Build_Tree(n, root->left, k + 1);
        }
    }
    else if (Huffq[n][k] == '1') {
        if (root->right == NULL) {
            q->word = '*';
            root -> right = q;
            Build_Tree(n, q, k + 1);
        }
        else {
            Build_Tree(n, root->right, k + 1);
        }
    }
}

void Readhfmtree() {
    char s[30];
    FILE *fp = NULL;
    fp = fopen("../hfmtree.txt", "r");
    if (fp == NULL) {
        printf("The document does not exist\n");
    }
    int sum = 0;
    while(!feof(fp)) {
        memset(s, '\0', sizeof(s));
        fgets(s, 30, fp);
        for (int i = 2; i < strlen(s); i++) {
            if (s[i] == '\n') {
                break;
            }
            Huffq[sum][i - 2] = s[i];
        }
        sum++;
    }
    fclose(fp);
    roott = (struct HT*) malloc(sizeof(struct HT));
    roott->left = NULL;
    roott->right = NULL;
    roott->word = '*';
    roott->val = 0;
    for (int i = 0; i < 27; i++) {
        Build_Tree(i, roott, 0);
    }
}

void sortt(int n) {
    for (int i = 0; i < n - 1; i++) {
        for(int j = i + 1; j < n; j++) {
            if (Huffman_Tree[i]->val < Huffman_Tree[j]->val) {
                struct HT *temp = Huffman_Tree[i];
                Huffman_Tree[i] = Huffman_Tree[j];
                Huffman_Tree[j] = temp;
            }
        }
    }
}

void Build_Bitt(struct HT *root, int k) {
    if (root == NULL) {
        return;
    }
    if (root->word >= 'A' && root->word <= 'Z') {
        memcpy(Huff[root->word - 'A'], root->bitt, k + 1);
        HuffLen[root->word - 'A'] = k;
    }
    else if (root->word == ' ') {
        memcpy(Huff[26], root->bitt, k + 1);
        HuffLen[26] = k;
    }
    if (root -> left != NULL) {
        memcpy(root->left->bitt, root->bitt, k + 1);
        root->left->bitt[k + 1] = false;
        Build_Bitt(root->left, k + 1);
    }
    if (root -> right != NULL) {
        memcpy(root->right->bitt, root->bitt, k + 1);
        root->right->bitt[k + 1] = true;
        Build_Bitt(root->right, k + 1);
    }
}

void Initialization() {
    char ch;
    int q;
    getchar();
    printf("input the letter and its val\n");
    for (int i = 0; i < 27; ++i) {
        scanf("%c %d", &ch, &q);
        struct HT *ht = (struct HT*)malloc(sizeof(struct HT));
        ht->word = ch;
        ht->val = q;
        ht->left = NULL;
        ht->right = NULL;
        memset(ht->bitt, false, sizeof(ht->bitt));
        getchar();
        if (ch == ' ') {
            Huffman_Tree[26] = ht;
        }
        else {
            Huffman_Tree[ch - 'A'] = ht;
        }
    }
    sortt(27);
    int m = 27;
    while(m != 1) {
        struct HT *ht = (struct HT *)malloc(sizeof(struct HT));
        ht->left = Huffman_Tree[m - 2];
        ht->right = Huffman_Tree[m - 1];
        ht->word = '*';
        ht->val = ht->left->val + ht->right->val;
        memset(ht->bitt, false, sizeof(ht->bitt));
        Huffman_Tree[m - 2] = ht;
        sortt(m);
        m--;
    }
    Build_Bitt(Huffman_Tree[0], 0);
    FILE *fp = NULL;
    fp = fopen("../hfmtree.txt","w");
    if (fp == NULL) {
        printf("Document Error");
    }
    for (int i = 0; i < 27; i++) {
        char s[30];
        memset(s, '\0', sizeof(s));
        if (i == 27 - 1) {
            s[0] = ' ';
        }
        else {
            s[0] = 'A' + i;
        }
        s[1] = ' ';
        for (int j = 1; j <= HuffLen[i]; ++j) {
            if (Huff[i][j] == false) {
                s[j + 1] = '0';
            }
            else {
                s[j + 1] = '1';
            }
        }
        fprintf(fp, s);
        fprintf(fp, "\n");
    }
    fclose(fp);
}

void Coding() {
    char s[300];
    memset(s, '\0', sizeof(s));
    gets(s);
    FILE *fp = NULL;
    fp = fopen("../codefile.txt","w");
    if (fp == NULL) {
        printf("Document Error");
    }
    for (int i = 0; i < strlen(s); i++) {
        if (s[i] >= 'A' && s[i] <= 'Z') {
            fprintf(fp, Huffq[s[i] - 'A']);
        }
        else if (s[i] == ' ') {
            fprintf(fp, Huffq[26]);
        }
        else {
            char ch[2];
            ch[0] = s[i];
            ch[1] = '\0';
            fprintf(fp, ch);
        }
    }
    fprintf(fp, "\n");
    fclose(fp);
};

void Decoding() {
    char s1[3000], s2[3000];
    FILE *fp1 = NULL, *fp2 = NULL;
    fp1 = fopen("../codefile.txt","r");
    fp2 = fopen("../textfile.txt","w");
    if (fp2 == NULL) {
        printf("Document Error");
    }
    if (fp1 == NULL) {
        printf("Document Not exist");
    }
    while (!feof(fp1)) {
        memset(s1, '\0', sizeof(s1));
        memset(s2, '\0', sizeof(s2));
        fgets(s1, 3000, fp1);
        struct HT *q = roott;
        int sum = 0;
        for (int i = 0; i < strlen(s1); ++i) {
            if (s1[i] == '0') {
                q = q->left;
            }
            else if (s1[i] == '1') {
                q = q->right;
            }
            else {
                s2[sum++] = s1[i];
            }
            if (q->word != '*') {
                s2[sum++] = q->word;
                q = roott;
            }
        }
        fprintf(fp2, s2);
        fprintf(fp2, "\n");
    }
    fclose(fp2);
    fclose(fp1);
}

void Print() {
    char s[1000];
    FILE *fp = NULL;
    fp = fopen("../codefile.txt","r");
    if (fp == NULL) {
        printf("Document Not exist");
    }
    while(!feof(fp)) {
        memset(s, '\0', sizeof(s));
        fgets(s, 1000, fp);
        for (int i = 0; i < strlen(s); ++i) {
            printf("%c", s[i]);
            if ((i + 1) % 50 == 0) {
                printf("\n");
            }
        }
    }
    fclose(fp);
}

void Tree_Print() {
    FILE *fp;
    fp = fopen("../treeprint.txt","w");
    if (fp == NULL) {
        printf("Document Error");
    }
    int sum = 30;
    char s[50];
    for (int i = 0; i < 27; ++i) {
        memset(s, '\0', sizeof(s));
        if (i == 26) {
            s[0] = ' ';
        }
        else {
            s[0] = 'A' + i;
        }
        s[1] = ' ';
        for (int j = 0; j < sum - strlen(Huffq[i]) * 2; ++j) {
            s[j + 2] = '=';
        }
        fprintf(fp, s);
        fprintf(fp,"\n");
        printf("%s\n",s);
    }
    fclose(fp);
}

int main() {
    char c;
    while (1) {
        printf(" 1.Initialization\n 2.Coding\n 3.Decoding\n 4.Print\n 5.Tree print\n");
        printf("input the number of the instruction to use the instructions, or input e/E to exit\n");
        scanf("%c",&c);
        if (c == 'E' || c == 'e') {
            break;
        }
        else {
            if (c == '1') {
                Initialization();
            }
            else if (c == '2') {
                Readhfmtree();
                getchar();
                Coding();
            }
            else if (c == '3') {
                Readhfmtree();
                Decoding();
            }
            else if (c == '4') {
                Print();
            }
            else if (c == '5') {
                Readhfmtree();
                Tree_Print();
            }
        }
    }
    return 0;
}

标签:fp,编码,int,root,Tree,else,译码,NULL,Huffman
来源: https://blog.csdn.net/transbit/article/details/122549833

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有