c++里用lzw压缩过后要怎么存入文件?
我用lzw算法压缩了一个文本,得到了三万多个数字,现在要怎么将这三万个数字保存到文本里,使得保存后文件的大小比原文件小呢
c++里用lzw压缩过后的数字要怎么存入文件
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
5条回答 默认 最新
语言-逆行者 2023-04-24 15:58关注基于new bing的编写:
将三万多个数字保存到文本文件里需要使用文件输出流,一般在 C++ 中使用 ofstream 类来实现。以下是一种可能的方式:
- 打开文件输出流并确定文件名和路径:
#include <fstream> using namespace std; ofstream fout("compressed.txt", ios::out | ios::binary);- 将压缩后的数字序列写入文件:
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 函数,并传入了输入文件名和输出文件名。需要注意的是,实际开发中应该根据具体需求进行修改和优化。此外,在解压缩时,也需要对压缩后的数据进行逆向操作,并根据压缩前的文件格式和编码方式进行还原。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报 编辑记录