添加头文件
This commit is contained in:
Ldong 2022-11-13 21:12:08 +08:00
parent 04551008b3
commit 73cb477411
2 changed files with 219 additions and 0 deletions

110
huffman_code.h Normal file
View File

@ -0,0 +1,110 @@
//
// Created by dongl on 22-11-13.
//
#ifndef CPP_DATA_STRUCT_HUFFMAN_CODE_H
#define CPP_DATA_STRUCT_HUFFMAN_CODE_H
#include <huffman_tree.h>
/// 解压缩 业务逻辑操作的类
class HTCode {
private:
char data_char{}; // 待编码的字符
std::byte code[10]{}; // 字符的解压缩编码
std::fstream file; // 文件流
//Huffman huffman; // 哈夫曼结构
Alphabet* alphabet; // 字符权重映射表
public:
HTCode* Open(const std::string& file_path, Alphabet* alpha = new Alphabet[27]){ // 记录字符与字符出现次数
// 记录字符数组的 初始化
// 初始化字符 出现次数 映射表 只支持中文
for (int i = 1; i <= 26; ++i) {
alpha[i].count = 0;
alpha[i].data = i + 97 - 1;
}
// 打开文件
file.open(file_path, std::ios::in);
if(!file.is_open()){
std::cerr << "open '" << file_path << "' fail" <<std::endl;
}
char c; // 字符
int c_count = 0;// 字母数量
int count = 0; // 压缩全文 多少个字符 总字符数
int ascii; // 字符的ascii
// 读取文件 统计字符个数
while (!file.eof()){
if(file.fail()) break;
file >> c;
count++;
ascii = (int) c;
// 小写 小写区间
if (ascii >= 65 && ascii <= 90){
// 65 - 65 + 1 下标 alpha[1]
alpha[ascii - 65 + 1].count++;
c_count++;
}
// 大写
if (ascii >= 97 && ascii <= 122){
alpha[ascii - 97 + 1].count++;
c_count++;
}
std::cout << c;
}
std::cout << std::endl;
std::cout << "总字符数" << count << "\n";
std::cout << "字母字符数" << c_count << "\n";
std::cout << "其他字符数" << count - c_count << std::endl;
file.close();
for (int i = 1; i <= 26; ++i) {
printf("[%d] : %c - %d \n", i, (char)alpha[i].data, alpha[i].count);
}
alphabet = alpha;
return this;
}
/// 建立哈夫曼表码表 利用哈夫曼树 将各个字符对应的编码表 保存在文件 {file}.txt.hmz
void CreateHuffmanCode(){
HuffmanTree ht = this->CreateHuffmanTree();
// 从叶子节点到根 逆向求每个字符的哈夫曼编码, 存在编码表中
char *cd = new char[26];
new char* [26 + 1];
cd[26-1] = '\0';
// for (int i = 1; i <= 26; ++i) {
// int start = 26 - 1;
// int c = i;
// auto f = ht[i].parent;
// while (f != 0){
// --start;
// if(f != 0){
//
// }
// }
// }
}
private:
HuffmanTree CreateHuffmanTree(){
HuffmanTree ht = (new Huffman(26, alphabet))->getHuffmanTree();
for (int i = 1; i <= 2 * 26 - 1; ++i) {
printf("下标%d值%c, 权重%d, ", i, ht[i].info, ht[i].weight);
std::cout << "双亲" << ht[i].parent <<", 左叶子" << ht[i].left << ", 右叶子" << ht[i].right << std::endl;
}
return ht;
}
};
#endif //CPP_DATA_STRUCT_HUFFMAN_CODE_H

109
huffman_tree.h Normal file
View File

@ -0,0 +1,109 @@
//
// Created by dongl on 22-11-11.
//
#ifndef CPP_DATA_STRUCT_HUFFMAN_TREE_H
#define CPP_DATA_STRUCT_HUFFMAN_TREE_H
#include <fstream>
#include <iostream>
/// 可变长度的字符串 树组
typedef char** huffman_code;
/// 哈夫曼节点结构 一棵树的节点结构
struct HTNodeBase {
struct HTNodeBase* parent; // 父节点
struct HTNodeBase* left; // 左子节点
struct HTNodeBase* right; // 右子节点
};
/// 哈夫曼节点结构 一棵树的节点信息
typedef struct HTNode : public HTNodeBase{
int weight; // 节点权重
int index; // 下标
char info; // 节点信息
} *HuffmanTree;
/// 字母信息 与 出现的次数
struct Alphabet {
char data; // 字符
int count; // 字母出现次数
};
/// 哈夫曼树 一棵树的结构
/// 构建树 操作树 的类
class Huffman{
private:
HuffmanTree ht; // 树根
int tree_node_sum{}; // 树的叶子数
public:
// 构建哈夫曼树
Huffman(int n, Alphabet* alphabet) {
// 如果节点小于1 没有必要构建 直接return
if (n <= 1)
return;
// 树的空间
// 0号单元未用 ht[2 * n - 1]表示根节点
int m = 2 * n - 1;
ht = new HTNode[m + 1];
// 构建树的全部节点
for (int i = 1; i <= m; ++i) {
ht[i].left = nullptr;
ht[i].right = nullptr;
ht[i].parent = nullptr;
}
// 构建存在个数节点的 字符与权重
for (int i = 1; i <= n; ++i) {
ht[i].weight = alphabet[i].count;
ht[i].info = alphabet[i].data;
}
// 正式 构建 构造 huffman 的节点关系 点与点之间的关系
for (int i = n+1; i < m; ++i) {
// 左右节点
int s1,s2;
SelectHuffmanTree(i, s1, s2);
// 表示从F中删除s1 ,s2
ht[i].left = &ht[s1];
ht[i].right = &ht[s2];
// s1 和 s2 分为为 i 的 左右叶子 权值为他俩的和
ht[i].weight = ht[s1].weight + ht[s2].weight;
}
}
HuffmanTree getHuffmanTree() {
return ht;
}
private:
/// 建立哈夫曼树 根据统计结果
/// @param ht
/// @param n
/// @param s1
/// @param s2
void SelectHuffmanTree(int n, int& s1, int& s2){
s1 = min_index(n - 1);
s2 = min_index(n - 1);
}
inline int min_index(int n){
int min;
int min_weight;
for (int i = 1; i <= n; ++i) {
// 没有父节点 未分配过的
if(ht[i].parent == nullptr){
min = i;
min_weight = ht[i].weight;
}
}
ht[min].parent = &ht[n + 1];
std::cout << "min=" << min << ", n=" << n << ", parent="
<< ht[min].parent << ", weight=" << ht[min].weight
<< ", info=" << ht[min].info << std::endl;
return min;
}
};
#endif //CPP_DATA_STRUCT_HUFFMAN_TREE_H