#include "stdafx.h"
#include<iostream>
using namespace std;
#include<fstream>
#include<string>
typedef struct {
char date;
int weight;
int parent,lchild,rchild;
}Htnode,*huffmanTree;
typedef char* * huffmancode;
void fun(Htnode *p,char a,int b)
{ p->date=a;
p->weight=b;
p->parent=p->lchild=p->rchild=0;
}
void select(huffmanTree & HT,int n,int &s1,int& s2)
{ //s1为权值最小的下标;s2为权值倒二小的下标;n为查找范围的最大下标;
int i;s1=10000;s2=10000;
for(i=1;i<=n;i++)
if(HT[i].parent==0)
{
if(HT[i].weight<s1)
{s2=s1;s1=i;}
else if(HT[i].weight<s2)
s2=i;
}
}
void Initialization(huffmanTree & HT ,huffmancode & HC,int &n)
{ int m,i=0;int*w;char*d;
ifstream in("G:\\1.txt");
in>>n;
if(n<=1)return ;
w=new int[n];d=new char[n];
d[0]=' ';
for(i=0;i<n;i++)
{ //in>>d[i];
if(i!=0)in>>d[i];
in>>w[i];
}
m=2*n-1; Htnode *p;
HT=(huffmanTree)malloc((m+1)*sizeof(Htnode));
for(p=HT+1,i=1;i<=n;++i,++p) fun(p,d[i-1],w[i-1]);
for( ;i<=m;++i,++p) fun(p,' ',0);
for(i=n+1;i<=m;++i)
{ int s1,s2;
select(HT,i-1,s1,s2);
HT[s1].parent=i;HT[s2].parent=i;
HT[i].lchild=s1;HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
//--------从叶子到根逆向求每个字符的哈夫曼树;
char*cd;
HC=(huffmancode)malloc((n+1)*sizeof(char*));
cd=(char*)malloc(n*sizeof(char));
cd[n-1]='\0';
for(i=1;i<=n;++i)
{ int start,c,f;
start=n-1;
for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)//从叶子到根逆向求编码;
if(HT[f].lchild==c)cd[--start]='0';
else cd[--start]='1';
HC[i]=(char*)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间;
strcpy(HC[i],&cd[start]);//从cd复制编码(串)到HC;
}
free(cd);//释放工作空间
}
void Encoding(huffmancode&HC,huffmanTree & HT,int n)
{
ofstream out("G:\\c.txt");
string s;int i,j;
cout<<"请输入信息:"<<endl;
getline(cin,s);
int num=s.length();
for(i=0;i<num;i++)
for(j=1;j<=n;j++)
if(s[i]==HT[j].date)
out<<HC[j];
out.close();
}
void Decoding(huffmancode&HC,huffmanTree & HT,int n)
{
string s,c;int j,i=0;char *p,*q;bool a=false;
ofstream out("G:\\t.txt");
ifstream in("G:\\c.txt");
getline(in,s);cout<<"s="<<s<<endl;
int t=s.length(); q=&s[0];p=q;
for(i=1;i<=n;i++)
{ c=HC[i];j=0;
while(c[j]!='\0')
{ if(*p !=c[j])
{a=true;break;}
p++;j++;
}
if(a){a=false;p=q;}
else
{ q=p;
out<<HT[i].date;
i=0;
if(*q==NULL)break;
}
}
}
void Print()
{ int i=0,j=0;string s;ifstream in("G:\\c.txt");
getline(in,s);
while(s[j]!='\0')
{ if(i++==49){i=0;cout<<s[j++]<<endl;}
else cout<<s[j++];
}}
void main()
{ huffmanTree HT; huffmancode HC;int n; Initialization(HT,HC,n);
Encoding(HC,HT,n); Decoding(HC,HT,n); Print();}