利用huffman树实现对文件A先编码后解码

news/2024/11/14 14:38:16/

利用huffman树实现对文件A先编码后解码,范围为ASCII码0-255的值,如何解决特殊符号问题是一个难点,注意应使用unsigned char存储数据,否则ASCII码128-255的值可能会出问题:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>
#include<map>
#include<vector>
const int N = 1e4;
using namespace std;
struct HuffmanNode
{int data;double weigh;int parent, lchild, rchild;
};
class HuffTree
{
private:vector<HuffmanNode>hufftree;map<int, vector<int>>eachcode;int n;//字符结点数
public:HuffTree() { hufftree.resize(0), n = 0; }void createHuffTree(vector<HuffmanNode>& leafs);~HuffTree();void GetCode(int c);//第i个符号的编码void SelectSmall(int& least, int& less, int i);void Decode(ifstream& is, ofstream& os);void geteachcode();string getcode(int ne);
};
void HuffTree::SelectSmall(int& least, int& less, int i)
{while ((hufftree[least].parent != -1 || hufftree[less].parent != -1)){if ((hufftree[least].parent != -1) || least == less)least++;if ((hufftree[less].parent != -1) || least == less) less++;}if (hufftree[least].weigh > hufftree[less].weigh)swap(least, less);for (int j = min(least, less); j < i; j++){if (j == least || j == less)continue;if (hufftree[j].parent == -1 && hufftree[j].weigh < hufftree[less].weigh){if (hufftree[j].weigh < hufftree[least].weigh){less = least;least = j;}else{less = j;}}}
}
void HuffTree::createHuffTree(vector<HuffmanNode>& leafs)
{n = leafs.size();hufftree.resize(2 * n - 1);for (int i = 0; i < n; i++){hufftree[i].data = leafs[i].data;hufftree[i].weigh = leafs[i].weigh;hufftree[i].lchild = hufftree[i].rchild = hufftree[i].parent = -1;}for (int i = n; i < 2 * n - 1; i++){int least = 0, less = 1;SelectSmall(least, less, i);hufftree[least].parent = hufftree[less].parent = i;hufftree[i].parent = -1;hufftree[i].lchild = least;hufftree[i].rchild = less;hufftree[i].weigh = hufftree[least].weigh + hufftree[less].weigh;}
}
void HuffTree::GetCode(int c)
{int i = 0;for (auto it = hufftree.begin(); it != hufftree.end(); it++){if (hufftree[i].data == c)break;i++;}if (i >= hufftree.size())return;int p = i;int parent = hufftree[i].parent;while (parent != -1){if (hufftree[parent].lchild == p)eachcode[c].insert(eachcode[c].begin(), 0);else eachcode[c].insert(eachcode[c].begin(), 1);p = parent;parent = hufftree[parent].parent;}
}
void HuffTree::geteachcode()
{for (auto it = eachcode.begin(); it != eachcode.end(); it++){cout << it->first << ":";for (int i = 0; i < it->second.size(); i++){cout << it->second[i];}cout << endl;}
}
string HuffTree::getcode(int ne)
{string res;for (int i = 0; i < eachcode[ne].size(); i++){res += to_string(eachcode[ne][i]);}return res;
}
void HuffTree::Decode(ifstream& is, ofstream& os)
{string target = "";int root = hufftree.size() - 1;int p = root;char c;while (is.get(c)){if (c == '0')p = hufftree[p].lchild;else p = hufftree[p].rchild;if (hufftree[p].lchild == -1 && hufftree[p].rchild == -1){unsigned char rchar=hufftree[p].data;os << rchar;p = root;}}
}
HuffTree::~HuffTree()
{}
int main()
{/*srand(time(0));ofstream out("random.txt");if (!out){cerr << "无法打开文件!" << endl;return 1;}for (int i = 0; i < N; i++){unsigned char rchar;rchar = rand() % 256;int data = rchar;out << rchar;}out.close();*/map<int, int>m;ifstream ifs_2("random.txt", ios::binary);char ch_1;while (ifs_2.get(reinterpret_cast<char&>(ch_1))){int data = static_cast<unsigned char>(ch_1);m[data]++;}ifs_2.close();map<int, double>m2;for (auto it = m.begin(); it != m.end(); it++){//m2[it->first] = static_cast<double>(it->second) / N;m2[it->first] = static_cast<double>(it->second);cout << it->first << "频率:" << m2[it->first] << endl;}HuffTree t;vector<HuffmanNode>leafs;leafs.resize(N);int i = 0;for (auto it = m2.begin(); it != m2.end(); it++){leafs[i].data = it->first;leafs[i].weigh = it->second;i++;}t.createHuffTree(leafs);for (int k = 0; k <= 255; k++){t.GetCode(k);}t.geteachcode();ifstream file("random.txt", ios::binary);string buf;char ch;ofstream os("B.txt", ios::binary);while (file.get(ch)){unsigned char uch = static_cast<unsigned char>(ch);int ne = uch;string is = t.getcode(ne);for (int i = 0; i < is.size(); i++){os << is[i];}}os.close();file.close();ofstream ofs("C.txt", ios::binary);ifstream ifs("B.txt", ios::binary);t.Decode(ifs, ofs);ofs.close();ifs.close();cout << "文件A与文件C的比较结果为: ";ifstream fileA("random.txt", ios::binary);ifstream fileC("C.txt", ios::binary);char bufA, bufC;while (fileA.get(bufA) && fileC.get(bufC)){if (bufA != bufC){cout << "不一致" << endl;return 0;}}cout << "一致" << endl;fileA.close();fileC.close();return 0;
}


http://www.ppmy.cn/news/1546484.html

相关文章

使用Matlab建立随机森林

综述 除了神经网络模型以外&#xff0c;树模型及基于树的集成学习模型是较为常用的效果较好的预测模型。我们以下构建一个随机森林模型。 随机森林是一种集成学习方法&#xff0c;通过构建多个决策树并结合其预测结果来提高模型的准确性和稳定性。在MATLAB中&#xff0c;可以…

HTML基础内容(详细版)

HTML 基础 HTML&#xff08;超文本标记语言&#xff0c;HyperText Markup Language&#xff09;是一种用于创建和设计网页的标准标记语言。它通过标签&#xff08;tags&#xff09;来定义网页的结构和内容。 基本HTML结构 常用HTML标签 1.标题标签&#xff1a; <h1> …

Win vscode 配置OpenGL时 undefined reference to `glfwInit‘

Win vscode 配置OpenGL时 undefined reference to glfwInit Win vscode 配置OpenGL时 undefined reference to glfwInit现象原因解决方案 Win vscode 配置OpenGL时 undefined reference to glfwInit’ 现象 win 上面用vscode 配置OpenGL 时会报一下错误 g -stdc17 -Wall -We…

rust模式和匹配

文章目录 match 分支参考 match 分支 所有结果都得匹配到 // Match Expressionfn main() {#[derive(Debug)]enum Language {English,Spanish,Russian,Japanese,}let language Language::English;match language {Language::English > println!("Hello World!")…

java ssm 个人学习管理系统 学习安排 学生在线学习管理 源码 jsp

一、项目简介 本项目是一套基于SSM的个人学习管理系统&#xff0c;主要针对计算机相关专业的和需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本、软件工具等。 项目都经过严格调试&#xff0c;确保可以运行&#xff01; 二、技术实现 ​后端技术&#x…

Vue中如何构建组件,支持传参、插槽等功能。

目录 1. 创建基本的Vue组件 2. 使用组件 3. 支持插槽 3.1 默认插槽 3.2 使用插槽 4. 作用域插槽 5. 使用作用域插槽 总结 在Vue.js中&#xff0c;组件是构建UI的基本单元&#xff0c;通过组件可以实现代码的复用和组织。以下是如何编写可复用的Vue组件的详细步骤&#…

vue3 + naive ui card header 和 title 冲突 bug

背景描述 最近发现一个 naive ui 上的问题&#xff0c;之前好好的&#xff0c;某一次升级后就出现了一个 bug&#xff0c;Modal 使用 card 布局后&#xff0c;Header Solt 下面的内容不见了&#xff0c;变成了 title&#xff0c;因为这个 solt 里面是有操作 action 的&#xf…

【DL】YOLO11 OBB目标检测 | 模型训练 | 推理

本文进行YOLO11的旋转目标检测任务,旋转目标检测能够更精确地定位和描述那些非水平排列的目标,比如倾斜的飞机、船舶等。在原始的目标检测中,添加一个角度预测,实现定向边界框检测。 话不多说,先来个效果图!!! YOLO11中的旋转目标检测的特点 ▲更精确的定位:通过使用…