实验二
目的要求:
掌握赫夫曼树和赫夫曼编码的基本思想和算法的程序实现。
实验内容:
实现文件中数据的加解密与压缩:将硬盘上的一个文本文件进行加密,比较加密文件和原始文件的大小差别;对加密文件进行解密,比较原始文件和解码文件的内容是否一致。
实验说明:
1.输入和输出:
(1)输入:硬盘上给定的原始文件及文件路径。
(2)输出:
硬盘上的加密文件及文件路径;
硬盘上的解码文件及文件路径;
原始文件和解码文件的比对结果。
2.实验要求:
提取原始文件中的数据(包括中文、英文或其他字符),根据数据出现的频率为权重,构建Huffman编码表;
根据Huffman编码表对原始文件进行加密,得到加密文件并保存到硬盘上;
将加密文件进行解密,得到解码文件并保存点硬盘上;
比对原始文件和解码文件的一致性,得出是否一致的结论。
//以下代码文件别太多字因为我开的数组小如果想稍微大点的文件可以边读边解码以
//及数组开的稍微大点, 还有 由于读文件不会读‘\n’ 我也不想解决了, 待后续小
//伙伴指正以及优化 (已更新 代码在下面)
#include "stdafx.h"
#include "iostream"
#include "string"
#include "cstdio"
#include "unordered_map" //不用unordered_map解码必须得一直遍历效率特别底下
//判断一个值是否存在 时间复杂度是o(1); map是o(logn)的
#include "fstream"
using namespace std;
const int N = 500;
int s[N]; // 存储huffmancoding
string HC[N]; // 字符编码映射字符 简单的map由于不让使用stl;
unordered_map<string, int> dc;
struct Node{
int c; //对应的字符
int weight; //权值
Node* l, *r; //左儿子和右儿子
} HTNode, *HuffmanTree;
Node* n[N]; // 存放指针数组存放 带频率的
int cnt = 1;
void down (int x, int len){
//堆排序小顶堆优化 构建huffman
Node* t = n[x];
for (int k = x * 2; k < len; k *= 2){
if (k + 1 < len && n[k] -> weight > n[k + 1] -> weight) k ++; //比较左右子树的大小
if (t -> weight > n[k] -> weight){
n[x] = n[k];
x = k;
}else //由于是已经够捡起来小顶堆 不成立就break
break;
}
n[x] = t;
}
void createHeap(int len){
for (int i = len / 2; i; i --){
down(i, len);
}
}
Node* createHuffTree(){
for (int i = 0; i < 500; i ++) //可以用map优化但没必要
if(s[i] != 0){
// 将得到的字符与其对应的出现次数创建节点
Node *t = (Node *)malloc(sizeof (Node));
t -> c = i;
t -> weight = s[i];
t ->l = NULL;
t -> r = NULL;
n[cnt ++] = t;
} //得到huffman节点
createHeap(cnt); //创建小顶堆
int len = cnt - 1;
while (len > 1){
Node* l = n[1];
n[1] = n[len];
len --;
down(1, len);
Node* r = n[1];
Node* cur = (Node *)malloc(sizeof (Node));
cur -> weight = l -> weight + r -> weight;
cur -> l = l;
cur -> r = r;
n[1] = cur;
down(1, len);
}
return n[1];
}
void getHuffcoding(Node * root