m0_62429719 2023-04-24 15:43 采纳率: 50%
浏览 87
已结题

c++里用lzw压缩过后的数字要怎么存入文件

c++里用lzw压缩过后要怎么存入文件?
我用lzw算法压缩了一个文本,得到了三万多个数字,现在要怎么将这三万个数字保存到文本里,使得保存后文件的大小比原文件小呢

  • 写回答

5条回答 默认 最新

  • 语言-逆行者 2023-04-24 15:58
    关注

    基于new bing的编写:
    将三万多个数字保存到文本文件里需要使用文件输出流,一般在 C++ 中使用 ofstream 类来实现。

    以下是一种可能的方式:

    1. 打开文件输出流并确定文件名和路径:
    #include <fstream>
    using namespace std;
    
    ofstream fout("compressed.txt", ios::out | ios::binary);
    
    
    1. 将压缩后的数字序列写入文件:
    int* compressedData; // 存储压缩后的数字序列
    int size; // 数字序列长度
    
    // 将数字序列一个一个写入到文件中
    for (int i = 0; i < size; i++) {
        fout.write(reinterpret_cast<char*>(&compressedData[i]), sizeof(int));
    }
    
    

    在这里,我们使用了 reinterpret_cast 来将 int 类型转换为 char* 类型,然后再向文件中写入。同时,由于数字是以二进制形式存储的,所以我们需要指定 ios::binary 标志位。

    另外,如果你需要在保存的文件中加入其它信息(如压缩前的文件名、大小等),可以先将这些元信息写入文件头部,然后再写入数字序列。

    需要注意的是,尽管使用 LZW 算法可以有效地压缩文本数据,但它仅适用于含有大量重复字符的文本数据。对于随机分布的数据,则可能无法得到很好的压缩效果,甚至可能导致压缩后的数据比原始数据更大。因此,在使用 LZW 算法之前,需要先对数据的特征进行分析和评估,以确定它是否适合使用该算法进行压缩。
    完整实现:

    
    #include <iostream>
    #include <fstream>
    #include <unordered_map>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    // 压缩函数
    void compress(string inputFilename, string outputFilename) {
        // 打开输入文件流
        ifstream fin(inputFilename, ios::in | ios::binary);
        if (!fin.is_open()) {
            cerr << "Failed to open " << inputFilename << endl;
            return;
        }
    
        // 打开输出文件流
        ofstream fout(outputFilename, ios::out | ios::binary);
        if (!fout.is_open()) {
            cerr << "Failed to create " << outputFilename << endl;
            return;
        }
    
        // 初始化字典
        unordered_map<string, int> dictionary;
        for (int i = 0; i < 256; i++) {
            dictionary[string(1, char(i))] = i;
        }
        int dictSize = 256;
    
        // 初始化当前前缀和下一个字符
        string currPrefix = "", nextChar = "";
        char c;
        fin.get(c);
        nextChar = c;
    
        // 压缩文本
        while (fin.good()) {
            currPrefix += nextChar;
            fin.get(c); // 读取下一个字符
            if (fin.eof()) break;
            nextChar = c;
            if (dictionary.find(currPrefix + nextChar) != dictionary.end()) {
                // 如果当前前缀加上下一个字符在字典中已存在,则继续读取下一个字符
                continue;
            } else {
                // 如果当前前缀加上下一个字符在字典中不存在,则将当前前缀的编码写入文件中,同时将当前前缀加上下一个字符加入字典
                fout.write(reinterpret_cast<char*>(&dictionary[currPrefix]), sizeof(int));
                dictionary[currPrefix + nextChar] = dictSize++;
                currPrefix = nextChar;
            }
        }
    
        // 将最后一个前缀的编码写入文件中
        if (currPrefix != "") {
            fout.write(reinterpret_cast<char*>(&dictionary[currPrefix]), sizeof(int));
        }
    
        // 关闭文件流
        fin.close();
        fout.close();
    }
    
    int main() {
        string inputFilename = "input.txt";
        string outputFilename = "compressed.bin";
        compress(inputFilename, outputFilename);
        return 0;
    }
    
    

    这段代码中,实现了一个名为 compress 的函数,用于将指定文件的文本数据进行压缩。该函数接收两个参数:输入文件名和输出文件名。在函数中,首先打开了输入文件流和输出文件流,并初始化了一个字典(采用无序哈希表实现)。然后,按照 LZW 算法的流程对输入文件中的文本进行压缩,并将压缩后的整型数据写入到输出文件中。最终关闭了文件流。

    主函数中,简单调用了 compress 函数,并传入了输入文件名和输出文件名。需要注意的是,实际开发中应该根据具体需求进行修改和优化。此外,在解压缩时,也需要对压缩后的数据进行逆向操作,并根据压缩前的文件格式和编码方式进行还原。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(4条)

报告相同问题?

问题事件

  • 系统已结题 5月3日
  • 已采纳回答 4月25日
  • 创建了问题 4月24日