Huffman encoding keeps the text in the file and automatically encodes

Features

Txt.txt needs to be created (save English text) and placed in the same folder as the .cpp file, or it can be placed on the desktop.

1. Can read all English characters

2. Automatically calculate the encoding and weight of all characters in the text (the number of times the character appears in the file) and save it in the HuffmanCode.txt file

3. The text can be encrypted according to the encoding and the encrypted text TxtToHu.txt obtained, and then translated into the text HuToTxt.txt using the Huffman tree

4. In addition to the Txt.txt file that needs to be created by yourself, other file programs are automatically created

Complete code

#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string>

using namespace std;

int NumOfChar;//字符种类 
int MaxSize; //静态链表实际使用大小 MAxsize-1也是哈夫曼树根结点的下标
const int MaxLen = 257;//256+1
typedef int Int;

typedef struct Node{
    
    
    int weight;//字符对应权重
    char c;//字符类型
    Int parent,lchild,rchild;//双亲指针,左右孩子指针
}HTNode;
HTNode Hu[MaxLen*2];//哈夫曼树结点数为2*n-1 

typedef struct HuCode{
    
    
    string code;
}HNode;

HNode HfCode[MaxLen];//用来存储哈夫曼编码
int Caculate[MaxLen];

void Get_CharInfo(void){
    
    //从文件中计算字符种类和权值 

	ifstream in;
	in.open("Txt.txt");
	
	char c;
	while(in.get(c)){
    
    //不到达文件末尾的情况下读取字符 
		Caculate[c] ++;//将读到的字符对应权重+1 
	}
	
	NumOfChar = 0;
	for(int i = 0;i < MaxLen;i++)
		if(Caculate[i]){
    
    //如果权重不为0 
			Hu[++NumOfChar].c = i;//存字符
			Hu[NumOfChar].weight = Caculate[i]; //存权重 
		}
	MaxSize = NumOfChar*2-1;//得到实际的哈夫曼树结点数量 
	in.close();//关闭文件 
	return;
}

void Creat_HuffmanTree(void){
    
    //建立哈夫曼树 
    int low1 = 0,low2 = 0;
    int indexofParent = NumOfChar+1;//第一个双亲结点下标 
   
    
    while(1){
    
    //找到权重最低的两个结点 

        low1 = low2 = 0;

        for(int i = 1;i < indexofParent;i++){
    
    //找low1
	        if(!low1 && !Hu[i].parent){
    
    //还没找到
	            low1 = i;
	        }else if(low1 && !Hu[i].parent && Hu[low1].weight > Hu[i].weight){
    
    
	            low1 = i;
	        }
    	}

	    for(int i = 1;i < indexofParent;i++){
    
    
	        if(i!=low1){
    
    
	            if(!low2 && !Hu[i].parent){
    
    //找low2
	                low2 = i;
	            }else if(low2 && !Hu[i].parent && Hu[low2].weight > Hu[i].weight){
    
    
	                low2 = i;
	            }
	        } 
	    }
	    
	    Hu[indexofParent].weight = Hu[low1].weight + Hu[low2].weight;//计算双亲结点的权重值 
	    Hu[indexofParent].lchild = low1;
	    Hu[indexofParent].rchild = low2;
	    Hu[low1].parent = indexofParent;
	    Hu[low2].parent = indexofParent;//low2为0 ???? 时indexofParent = 8指针越界 
	    
	    if(indexofParent == MaxSize){
    
    //如果哈夫曼树已经构建完成就退出  
	    	break; //已经构建 MaxSize个结点 
		}
	       
	    indexofParent++;//下个父节点位置 
	
	    }
	    
	return;
}

void Create_Huffman_Code(int index,string scode){
    
    //通过哈夫曼树建立哈夫曼编码 
		
        //index 初始值为根结点 
        if(Hu[index].lchild){
    
     //说明该结点不是叶子结点
            scode.append("0");
            Create_Huffman_Code(Hu[index].lchild,scode);

            scode = scode.substr(0,scode.length()-1);//删除末尾元素 向右子树搜索
            scode.append("1");
            Create_Huffman_Code(Hu[index].rchild,scode);
        }
        else    HfCode[(int)(Hu[index].c)].code = scode;//否则该字符完成编码
    return;
}

void Print_HuffmanCodeToFile(void){
    
    //将 字符 权重 编码 输入到文件中 
	ofstream in;
	in.open("HuffmanCode.txt");
	for(int i = 1;i <= NumOfChar;i++){
    
    
		in << "字符:" << Hu[i].c << " 权重:" << Hu[i].weight << " 编码:" <<HfCode[Hu[i].c].code<<endl;
	}
	in.close();
	return;
}

void Txt_To_Huffmantxt(void){
    
    //文本转哈夫曼编码 

    
    ifstream in;
	in.open("Txt.txt");
    
    ofstream out;
	out.open("TxtToHu.txt");
   
    char c;
   
    while(in.get(c)){
    
    
        out << HfCode[(int)c].code;
    }
    
    in.close();
    out.close();
    return;
}

void HuffmantxtToTxt(void){
    
    //哈夫曼编码转文本 
	
    ifstream in;
	in.open("TxtToHu.txt");
   
    ofstream out;
	out.open("HuToTxt.txt");
    
    char c;
    int index = MaxSize;
    
    while(in.get(c)){
    
     
    	
        if(c == '1'){
    
    //1
            if(Hu[Hu[index].rchild].rchild){
    
    //如果指向的结点不是叶子结点 
                index = Hu[index].rchild;//通过该结点是否有孩子来判断 
            }else{
    
    //是叶子结点 
                out << Hu[Hu[index].rchild].c;
                index = MaxSize;//回到根结点
            }
        }else{
    
    //0
            if(Hu[Hu[index].lchild].lchild){
    
    
                index = Hu[index].lchild;
            }else{
    
    
                out << Hu[Hu[index].lchild].c;
                index = MaxSize;
            }
        }
		
    }
    in.close();
    out.close();
    return;
}

int main(){
    
    
	
    
    string scode = "";//string 赋空 
	Get_CharInfo();//获取字符和权值 
    Creat_HuffmanTree();//建立哈夫曼树
   
    Create_Huffman_Code(MaxSize,scode);//建立哈夫曼编码
    
   	Print_HuffmanCodeToFile(); //将设计的编码输出到文件中 
    
    Txt_To_Huffmantxt();//通过查找字符对应的编码 将文本转换为编码文件
    
    HuffmantxtToTxt();//通过哈夫曼树 将编码文件转换为文本。
  
   //system("pause");
	return 0;
}

Guess you like

Origin blog.csdn.net/RunningBeef/article/details/111668605