文件压缩程序的设计与实现代码C++
时间: 2023-12-29 14:45:39 浏览: 51
以下是一个简单的文件压缩程序的设计与实现代码 C++:
```c++
#include<iostream>
#include<fstream>
#include<cstring>
#include<cstdlib>
using namespace std;
// 定义常量
const int MAXCHAR = 256; // 最大字符数
const int MAXNODE = 511; // 最大节点数
const int MAXBIT = 1000; // 最大比特数
// 压缩文件结构体
struct compressfile {
char name[100]; // 文件名
int freq[MAXCHAR]; // 字符出现频率
char code[MAXCHAR][MAXBIT]; // 字符编码
int len[MAXCHAR]; // 字符编码长度
} cf;
// 哈夫曼树结点结构体
struct node {
int freq; // 字符出现频率
int parent, lchild, rchild; // 父节点、左孩子、右孩子
} tree[MAXNODE];
// 创建哈夫曼树
void createTree(int n) {
int i, j, x1, x2;
double min1, min2;
for (i = 1; i <= n; i++) {
tree[i].freq = cf.freq[i - 1];
tree[i].parent = tree[i].lchild = tree[i].rchild = 0;
}
for (i = n + 1; i <= 2 * n - 1; i++) {
min1 = min2 = 1e9;
x1 = x2 = 0;
for (j = 1; j < i; j++) {
if (!tree[j].parent) {
if (tree[j].freq < min1) {
min2 = min1;
x2 = x1;
min1 = tree[j].freq;
x1 = j;
} else if (tree[j].freq < min2) {
min2 = tree[j].freq;
x2 = j;
}
}
}
tree[x1].parent = i;
tree[x2].parent = i;
tree[i].lchild = x1;
tree[i].rchild = x2;
tree[i].freq = tree[x1].freq + tree[x2].freq;
}
}
// 编码
void encode(int n) {
int i, j, k, p;
char code[MAXBIT];
for (i = 0; i < n; i++) {
p = i + 1;
k = 0;
j = tree[p].parent;
while (j) {
if (tree[j].lchild == p) code[k++] = '0';
else code[k++] = '1';
p = j;
j = tree[p].parent;
}
code[k] = '\0';
strcpy(cf.code[i], strrev(code));
cf.len[i] = k;
}
}
// 压缩文件
void compress(char *filename) {
char *p, c;
int i, j, len, sum = 0;
ifstream fin(filename, ios::binary);
while (!fin.eof()) {
fin.get(c);
if (fin.eof()) break;
cf.freq[c]++;
sum++;
}
fin.close();
createTree(256);
encode(256);
p = strrchr(filename, '.');
strcpy(cf.name, filename);
len = strlen(cf.name);
cf.name[len] = 'h';
cf.name[len + 1] = 'f';
cf.name[len + 2] = '\0';
ofstream fout(cf.name, ios::binary);
fout.write((char *) &sum, sizeof(int));
for (i = 0; i < 256; i++)
fout.write((char *) &cf.freq[i], sizeof(int));
fin.open(filename, ios::binary);
c = 0;
len = 0;
while (!fin.eof()) {
fin.get(p[0]);
if (fin.eof()) break;
i = p[0];
len += cf.len[i];
for (j = 0; j < cf.len[i]; j++) {
c <<= 1;
if (cf.code[i][j] == '1') c |= 1;
if (len == 8) {
fout.put(c);
c = 0;
len = 0;
}
}
}
if (len > 0) {
c <<= (8 - len);
fout.put(c);
}
fin.close();
fout.close();
}
// 解压缩文件
void decompress(char *filename) {
char *p, c, code[MAXBIT];
int i, j, len, sum = 0;
ifstream fin(filename, ios::binary);
fin.read((char *) &sum, sizeof(int));
for (i = 0; i < 256; i++)
fin.read((char *) &cf.freq[i], sizeof(int));
createTree(256);
p = strrchr(filename, '.');
p++;
*p = 'd';
*(p + 1) = 'a';
*(p + 2) = 't';
*(p + 3) = '\0';
ofstream fout(p, ios::binary);
len = 0;
i = 2 * MAXNODE - 2;
while (sum > 0) {
fin.get(c);
for (j = 7; j >= 0 && sum > 0; j--) {
if ((c >> j) & 1) i = tree[i].rchild;
else i = tree[i].lchild;
if (!tree[i].lchild) {
fout.put(i);
sum--;
i = 2 * MAXNODE - 2;
}
}
}
fin.close();
fout.close();
}
int main() {
char filename[100];
int choice;
while (true) {
cout << "1. 压缩文件" << endl;
cout << "2. 解压缩文件" << endl;
cout << "3. 退出" << endl;
cout << "请选择:";
cin >> choice;
switch (choice) {
case 1:
cout << "请输入要压缩的文件名:";
cin >> filename;
compress(filename);
cout << "压缩完成!" << endl;
break;
case 2:
cout << "请输入要解压缩的文件名:";
cin >> filename;
decompress(filename);
cout << "解压缩完成!" << endl;
break;
case 3:
exit(0);
default:
cout << "输入错误,请重新输入!" << endl;
}
}
return 0;
}
```
该程序实现了简单的文件压缩和解压缩功能,使用哈夫曼编码实现数据压缩,具体实现过程在代码注释中进行了解释。
阅读全文