ZBLOG

#include #include #include #define MAX_BITS 100 #define NUM_LETTERS 26 #define MAX_CHAR 26 struct node { char c; // 字母 int freq; // 出现次数 struct node *left; // 左子节点 struct node *right; // 右子节点 }; st...

和解压缩功能。

// 压缩函数 void compress(FILE *fp_in, FILE *fp_out, struct node *root) {

char buffer[MAX_BITS] = {'\0'}; // 初始化缓冲区
int index = 0;
char c;
while ((c = fgetc(fp_in)) != EOF) {
    if (c >= 'A' && c <= 'Z') { // 如果是大写字母
        struct node *curr = root;
        while (curr->c != c) { // 寻找对应的叶子节点
            if (buffer[index++] == '0') {
                curr = curr->left;
            } else {
                curr = curr->right;
            }
        }
        strcat(buffer, code); // 将编码加入到缓冲区中
        while (strlen(buffer) >= MAX_BITS) { // 当缓冲区满时输出到文件中
            unsigned char byte = 0; // 使用一个字节存储数据
            for (int i = 0; i < MAX_BITS; i++) {
                byte <<= 1; // 左移一位,相当于乘以2
                if (buffer[i] == '1') { // 如果该位为1则加上1
                    byte |= 1;
                }
            }
            fwrite(&byte, sizeof(unsigned char), 1, fp_out); // 将字节写入文件中
            memmove(buffer, buffer + MAX_BITS, strlen(buffer) - MAX_BITS + 1); // 移除已经处理的部分,保留未处理的部分继续处理
        }
    }
}
if (index > 0) { // 处理剩余的部分
    strcat(buffer, code);
    int padding = MAX_BITS - strlen(buffer); // 计算需要补充的位数
    for (int i = 0; i < padding; i++) {
        buffer[strlen(buffer)] = '0'; // 在缓冲区末尾添加0
    }
    unsigned char byte = 0;
    for (int i = 0; i < MAX_BITS; i++) {
        byte <<= 1;
        if (buffer[i] == '1') {
            byte |= 1;
        }
    }
    fwrite(&byte, sizeof(unsigned char), 1, fp_out); // 将字节写入文件中
}

}

// 解压函数 void decompress(FILE *fp_in, FILE *fp_out, struct node *root) {

struct node *curr = root;
unsigned char byte;
while (fread(&byte, sizeof(unsigned char), 1, fp_in) != EOF) { // 每次读取一个字节
    for (int i = MAX_BITS - 1; i >= 0; i--) { // 对每个位进行处理
        if (byte & (1 << i)) { // 如果该位为1,则向右走,否则向左走
            curr = curr->right;
        } else {
            curr = curr->left;
        }
        if (!curr->left && !curr->right) { // 如果到达叶子节点,则输出对应的字符,并重置当前节点为根节点继续处理下一个字符
            fprintf(fp_out, "%c", curr->c);
            curr = root;
        }
    }
}

}

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=4902

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?