哈夫曼编码的译码解码全代码

录入内容的部分并不完整,仅供参考,但是可以运行,需要自行根据需要补充完整

#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;
}