⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 huffman.cpp

📁 哈夫曼编码器
💻 CPP
字号:
#include <fstream>
#include "huffman.h"

huffman::~huffman()
{
	delete[] hft;
}

huffman::huffman()
{
	hft=NULL;
	n=0;
}

bool filenamestd(string &filename)
{
	if(filename.find(".txt")==string::npos)
		filename=filename+".txt";
	return true;
}

bool fileprint(string filename)
{
	int i;
	char ch;
	ifstream infile;
	filenamestd(filename);
	infile.open(filename.c_str());
	system("cls");
	cout<<filename<<endl;
	while(1)
	{
		for(i=0;i<60;i++)
		{
			infile.get(ch);
			if(!infile) break;
			cout<<ch;
		}
		cout<<endl;
		if(!infile) break;
	};
	infile.close();
	ch=getch();
	return true;
}

bool huffman::writehfm(string filename)
{
	int i;
	if(!filenamestd(filename)) return false;
	ofstream outfile;
	outfile.open(filename.c_str());
	outfile<<"这是一个赫夫曼树文件:第一个为字符元素个数,后面为树结构。"<<endl;
	outfile<<n<<endl;
	for(i=1;i<2*n;i++)
		outfile<<hft[i].elem<<' '<<hft[i].weight<<' '<<hft[i].parent<<' '<<hft[i].lchild<<' '<<hft[i].rchild<<endl;
	outfile.close();
	return true;
}

bool huffman::readhfm(string filename)
{
	int i;
	if(!filenamestd(filename)) return false;
	ifstream infile;
	infile.open(filename.c_str());
	infile.ignore(1000,'\n');
	infile>>n;
	infile.ignore(100,'\n');
	hft=new hfnode[2*n];
	for(i=1;i<2*n;i++)
	{
		infile.get(hft[i].elem);
		infile>>hft[i].weight>>hft[i].parent>>hft[i].lchild>>hft[i].rchild;
		infile.ignore(100,'\n');
	}
	infile.close();
	return true;
}

bool huffman::readdate()
{
	int i;
	cout<<"请输入字符种类的个数:";
	cin>>n;
	cin.ignore(100,'\n');
	cout<<"请输入各字符及其权重:"<<endl;
	hft=new hfnode[2*n];
	for(i=1;i<=n;i++)
	{
		hft[i].lchild=0;
		hft[i].rchild=0;
		hft[i].parent=0;
		cin.get(hft[i].elem);
		cin>>hft[i].weight;
		cin.ignore(100,'\n');
	}
	for(;i<=2*n-1;i++)
	{
		hft[i].lchild=0;
		hft[i].rchild=0;
		hft[i].parent=0;
		hft[i].elem=-1;
		hft[i].weight=0;
	}
	return true;
}


bool huffman::selectmin(int m,int &lc,int &rc)
{
	int i,wmin;
	for(i=1,wmin=-1;i<=m;i++)
	{
		if(hft[i].parent==0)
		{
			if(wmin==-1)
			{
				wmin=hft[i].weight;
				lc=i;
			}
			else
			{
				if(wmin>hft[i].weight)
				{
					wmin=hft[i].weight;
					lc=i;
				}
			}
		}
	}

	for(i=1,wmin=-1;i<=m;i++)
	{
		if(hft[i].parent==0&&i!=lc)
		{
			if(wmin==-1)
			{
				wmin=hft[i].weight;
				rc=i;
			}
			else
			{
				if(wmin>hft[i].weight)
				{
					wmin=hft[i].weight;
					rc=i;
				}
			}
		}
	}
	return false;
}

bool huffman::creathuffmantree()
{
	string filename;
	int i,lc,rc;
	char bd;
	readdate();
	for(i=n+1;i<=(2*n-1);i++)
	{
		selectmin(i-1,lc,rc);
		hft[lc].parent=i;
		hft[rc].parent=i;
		hft[i].weight=hft[lc].weight+hft[rc].weight;
		hft[i].lchild=lc;
		hft[i].rchild=rc;
	}
	do
	{
		cout<<endl;
		cout<<"是否保存此赫夫曼树?(y/n):";
		bd=getch();
	}while(bd!='y'&&bd!='n');
	cout<<endl;
	if(bd=='y')
	{
		cout<<"请输入文件名:";
		cin>>filename;
		writehfm(filename);
		cout<<"树文件保存成功!"<<endl;
		bd=getch();
	}
	return true;
}

bool huffman::creathuffmantree(string filename)
{
	char bd;
	if(readhfm(filename))
		cout<<"读取树文件成功!"<<endl;
	bd=getch();
	return true;
}

bool huffman::encoding(string filename)
{
	int i,c,f,start;
	char ch,*cd,bd;
	string outfilename;
	filenamestd(filename);
	ifstream infile;
	ofstream outfile;
	infile.open(filename.c_str());
	cout<<"请输入编码输出文件名:";
	cin>>outfilename;
	filenamestd(outfilename);
	outfile.open(outfilename.c_str());
	cd=new char[n];
	cd[n-1]='\0';
	while(1)
	{
		infile.get(ch);
		if(!infile) break;
		for(i=1;ch!=hft[i].elem;i++);
		start=n-1;
		for(c=i,f=hft[i].parent;f!=0;c=f,f=hft[f].parent)
		{
			if(hft[f].lchild==c)
				cd[--start]='0';
			else
				cd[--start]='1';
		}
		for(;cd[start]!='\0';start++)
			outfile<<cd[start];
	}
	infile.close();
	outfile.close();
	do
	{
		cout<<"是否想打印编码?(y/n):";
		bd=getch();
	}while(bd!='y'&&bd!='n');
	cout<<endl;
	if(bd=='y')
		fileprint(outfilename);
	return true;
}

bool huffman::decoding(string filename)
{
	int p;
	char ch,bd;
	string outfilename;
	filenamestd(filename);
	ifstream infile;
	ofstream outfile;
	infile.open(filename.c_str());
	cout<<"请输入译码输出文件名:";
	cin>>outfilename;
	filenamestd(outfilename);
	outfile.open(outfilename.c_str());
	p=2*n-1;
	while(1)
	{
		if(hft[p].elem==-1)
		{
			infile.get(ch);
			if(!infile) break;
			if(ch=='0')
				p=hft[p].lchild;
			else
				p=hft[p].rchild;
		}
		else
		{
			outfile<<hft[p].elem;
			p=2*n-1;
		}
	}
	infile.close();
	outfile.close();
	do
	{
		cout<<"是否想打印译码?(y/n):";
		bd=getch();
	}while(bd!='y'&&bd!='n');
	cout<<endl;
	if(bd=='y')
		fileprint(outfilename);
	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -