111 lines
3.3 KiB
C++
111 lines
3.3 KiB
C++
//
|
||
// 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
|