哈夫曼编码的译码解码全代码
录入内容的部分并不完整,仅供参考,但是可以运行,需要自行根据需要补充完整
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
typedef struct Hufman {
int parent=0;
char data;
double weight=0.0;
int lchild=0;
int rchild=0;
}*HufmanTree;
typedef struct HufmanCode {
char* ch;
char data;
}HufmanCode,*hufmancode;
void addData(hufmancode hc, HufmanTree hf,int n);
void save(const hufmancode hf,int n);
void Select(HufmanTree& HT,int x, int& s1, int& s2)
{
//寻找第一个双亲域为0且权值最小的结点
int min=0;
for (int i = 1; i <= x; i++) //找到第一个双亲域为0的,下标暂存到min
{
if (HT[i].parent == 0)
{
min = i;
break;
}
}
for (int i = 1; i <= x; i++)
{
if (HT[i].parent == 0)
{
if (HT[i].weight < HT[min].weight)
{
min = i;
}
}
}
s1 = min;
//寻找第二个双亲域为0且权值最小的结点
for (int i = 1; i <= x; i++) //找到第一个双亲域为0的,下标暂存到min
{
if (HT[i].parent == 0 && i != s1)
{
min = i;
break;
}
}
for (int i = 1; i <= x; i++)
{
if (HT[i].parent == 0 && i != s1)
{
if (HT[i].weight < HT[min].weight)
{
min = i;
}
}
}
s2 = min;
}
void addData(hufmancode hc, HufmanTree hf,int n) {
//将哈夫曼树中的数据保存到哈夫曼编码的结构体当中
for (int i = 1; i <= n; i++) {
hc[i].data = hf[i].data;
}
}
void save(const hufmancode hf,int n) {
//保存获得的每个字母对应的哈夫曼编码
ofstream ofs;
ofs.open("哈夫曼编码值.txt", ios::out);
for (int i = 1; i <= n; i++) {
ofs << hf[i].data << " " << hf[i].ch << endl;
}
ofs.close();
}
void putPassage() {
//输入想要转换为哈夫曼编码的内容
ofstream ofs;
ofs.open("英文电报.txt", ios::out);
cout << "请输入电报内容(连续不带有空格): " << endl;
string str;
cin >> str;
ofs << str;
ofs.close();
return;
}
int num;
void getWeight() {
//获取每个字母的权值
int countA = 0;
int countB=0;
int countC=0;
int countD=0;
double aw = 0.0;
double bw = 0.0;
double cw = 0.0;
double dw = 0.0;
ifstream ifs;
ifs.open("英文电报.txt", ios::in);
string str;
ifs >> str;
for (int i = 0; i < str.length(); i++) {
if (str[i] == 'A') {
++countA;
++num;
}
if (str[i] == 'B') {
++countB;
++num;
}
if (str[i] == 'C') {
++countC;
++num;
}
if (str[i] == 'D') {
++countD;
++num;
}
}
ifs.close();
aw = (double)countA / num;
bw = (double)countB / num;
cw = (double)countC / num;
dw = (double)countD / num;
ofstream ofs;
ofs.open("结点及其权值的存储.txt", ios::out);
ofs << "A" << " "<<aw << endl;
ofs << "B" << " "<<bw << endl;
ofs << "C" << " "<<cw << endl;
ofs << "D" << " "<<dw << endl;
ofs.close();
}
void createHufmanTree(HufmanTree& hf,int n) {
//构建哈夫曼树
int value1 = 0;
int value2 = 0;
if (hf == nullptr)
return;
int m = 2 * n - 1;
hf = new Hufman[m + 1];
ifstream ifs;
ifs.open("结点及其权值的存储.txt", ios::in);
for (int i = 1; i <= n; i++) {
ifs>> hf[i].data >> hf[i].weight;
}
for (int j = (n + 1); j <= m; j++) {
Select(hf, j - 1, value1, value2);
hf[j].lchild = value1;
hf[j].rchild = value2;
hf[value1].parent = j;
hf[value2].parent = j;
hf[j].weight = hf[value1].weight + hf[value2].weight;
}
}
void CreateHufmanCode(HufmanTree ht, hufmancode& hc,int n) {
//创建哈夫曼编码
hc = new HufmanCode[n + 1];
char* cd = new char[n];
cd[n - 1] = '\0';
for (int i = 1; i <= n; i++) {
int start = n - 1;
int c = i;
int f = ht[i].parent;
while (f != 0) {
--start;
if (ht[f].lchild == c)
cd[start] = '0';
if (ht[f].rchild == c)
cd[start] = '1';
c = f;
f = ht[f].parent;
}
hc[i].ch = new char[n - start];
strcpy(hc[i].ch, &cd[start]);
}
addData(hc, ht,n);
save(hc,n);
delete[] cd;
}
typedef struct Node {
char data;
string code;
}Node;
void changetohufman() {
//存储电报转换后的哈夫曼编码值
ifstream ifs;
ifs.open("英文电报.txt", ios::in);
string str;
ifs >> str;
ifs.close();
ifs.open("哈夫曼编码值.txt", ios::in);
Node* n = new Node[4];
for (int i = 0; i < 4; i++) {
ifs >> n[i].data >> n[i].code;
}
ofstream ofs;
ofs.open("获得的哈夫曼编码.txt", ios::out);
for (int i = 0; i < str.length(); i++) {
bool flag = true;
for (int j = 0; j < 4&&flag; j++) {
if (str[i] == n[j].data) {
ofs << n[j].code;
flag = false;
}
}
}
ofs.close();
delete[] n;
}
void showCode() {
//展示转换结果
ifstream ifs;
ifs.open("获得的哈夫曼编码.txt", ios::in);
string str;
ifs >> str;
cout << str;
}
void changetoChar() {
ifstream ifs;
ifs.open("获得的哈夫曼编码.txt", ios::in);
string str;
ifs >> str;
ifs.close();
ifs.open("哈夫曼编码值.txt", ios::in);
Node* n = new Node[4];
for (int i = 0; i < 4; i++) {
ifs >> n[i].data >> n[i].code;
}
ifs.close();
string temp = "";
string last="";
for (int i = 0; i < str.size(); i++) {
temp = temp + str[i];
for (int j = 0; j < 4; j++) {
if (n[j].code == temp) {
last += n[j].data;
temp = "";
break;
}
else if (i == str.length() - 1 && j == 3 && temp != "") {
cout << "解码错误" << endl;
}
}
}
ofstream ofs;
ofs.open("哈夫曼码转换为电报内容.txt", ios::out);
ofs << last;
ofs.close();
return;
delete[] n;
}
int main() {
putPassage();
getWeight();
HufmanTree ht;
hufmancode hc;
cout << "请输入叶子结点的数目(4) :" << endl;
int n;
cin >> n;
createHufmanTree(ht, n);
CreateHufmanCode(ht, hc, n);
changetohufman();
changetoChar();
showCode();
return 0;
}