You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

295 lines
9.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <iostream>
#include <fstream>
#include <cassert>
#include <string>
#include <string.h>
using namespace std;
struct HNode
{
HNode *parent;
HNode *lch, *rch;
int weight,codelen;
char data;
char *code; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD>ָ<EFBFBD>
typedef HNode* HTree;
typedef HNode* ElemType;
//˳<><CBB3><EFBFBD>
typedef struct
{
ElemType *elem;
int length; //<2F><>ǰ<EFBFBD><C7B0><EFBFBD>ݵ<EFBFBD>ʵ<EFBFBD>ʳ<EFBFBD><CAB3><EFBFBD>(<28>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
} seqList;
//<2F><><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD>ht<68><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ź<EFBFBD><C5B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD>
seqList ht;
//<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҷ<EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD>뵽˳<EBB5BD><CBB3><EFBFBD>
//a:Ȩֵ<C8A8><D6B5>b<EFBFBD><62>Ҷ<EFBFBD><D2B6><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>n<EFBFBD><6E>Ҷ<EFBFBD><D2B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void input(int a[], char b[], int n)
{
for (int i = 0; i < n; i++)
{
HNode *tmp = new HNode;
tmp->parent = NULL;
tmp->weight = a[i];
tmp->data = b[i];
tmp->lch = NULL;
tmp->rch = NULL;
ht.elem[i]=tmp;
ht.length++;
}
}
// n:<3A>±<EFBFBD>Ϊ[0~n)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>n<EFBFBD><6E><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD>ht<68><74> 0~n<><6E>ѡ<EFBFBD><D1A1>2<EFBFBD><32>Ȩֵ<C8A8><D6B5>С<EFBFBD>Ľ<EFBFBD><EFBFBD><E3A3AC><EFBFBD><EFBFBD>±<EFBFBD><C2B1>ŵ<EFBFBD>s1,s2<73><32>
void selectMin(int n, int &s1, int &s2)
{
int m1 = 0x7fff;
int m2 = 0x7fff; // m1ȡ<31><C8A1>СȨ<D0A1>أ<EFBFBD>m2ȡ<32><C8A1>СȨ<D0A1><C8A8>
int lnode = 0;
int rnode = 0; // lnode, rnode<64>ֱ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>СȨ<D0A1>صĽ<D8B5><C4BD>λ<EFBFBD><CEBB>
for(int k=0; k<n; k++){
if(ht.elem[k]->parent==NULL){
if(ht.elem[k]->weight<m1) {
m2 = m1; rnode=lnode;
m1 = ht.elem[k]->weight; lnode=k;
}
else if(ht.elem[k]->weight<m2) {
m2 =ht.elem[k]->weight;
rnode = k;
}
}
}
s1=lnode;
s2=rnode;
}
//<2F><><EFBFBD><EFBFBD>n<EFBFBD><6E>Ҷ<EFBFBD>ӽ<EFBFBD><EFBFBD><E3B4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cht<68><74>
void creatHt(HTree &cht, int n)
{
HNode tNode;
int m = 2 * n - 1;
int s1, s2;
//<2F><>ʼ0~n-1<><31>ѡ
for (int i = n; i < m; i++)
{
HNode *r = new HNode;
r->parent = NULL;
selectMin(i, s1, s2);
r->weight=ht.elem[s1]->weight+ht.elem[s2]->weight;
r->lch=ht.elem[s1];
r->rch=ht.elem[s2];
ht.elem[s1]->parent=r;
ht.elem[s2]->parent=r;
ht.elem[i]=r;
ht.length++;
}
cht = ht.elem[m-1];
}
void printHfTreePre(HTree t)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
if (t != NULL)
{
if (t->lch == NULL && t->rch == NULL)
{
cout << "weight:" << t->weight << " " << t->data << ":" <<t->code << endl;//
}
printHfTreePre(t->lch);
printHfTreePre(t->rch);
}
}
void hufmadecode(char* filename,HTree t,char *ziped,int len){//<2F><><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD>ĵ<EFBFBD>
ifstream infile(filename);
if(!infile.is_open()){
cerr<<"ifstream open file error\n";
return;
}
infile.seekg(0,ios_base::end);
int length = infile.tellg();
infile.seekg(ios_base::beg);
char* buff=new char[length+1]();
infile.read(buff,length+1);
int count =0;
for(int i=0;i<length+1;i++){
for(int j=0;j<len;j++){
if(buff[i]==ht.elem[j]->data){
strcpy(ziped+count,ht.elem[j]->code);
count+=ht.elem[j]->codelen;
break;
}
}
}
ziped[count+1]='\0';
infile.close();
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>±<EFBFBD><C2B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void hufEncode(HTree t, int k, char *code)
{
if (t == NULL)
return;
if (t->lch == NULL && t->rch == NULL)
{
code[k] = '\0';
t->code = new char[k + 1];
strncpy(t->code, code ,k + 1);
t->codelen=k;
}
if(t->lch != NULL){
code[k]='0';
hufEncode(t->lch, k+1, code);
}
if(t->rch != NULL){
code[k]='1';
hufEncode(t->rch, k+1, code);
}
}
//<2F><><EFBFBD><EFBFBD>: <20><><EFBFBD><EFBFBD><EFBFBD>dec<65><63>
void hufDecode(HTree &ht, char str[], char *dec)
{
HNode *t = ht;
while (*(str+1))
{
if(*str=='0')t=t->lch;
else t=t->rch;
if(t->lch==NULL&&t->rch==NULL){
cout<<t->data;
t=ht;
}
str++;
}
}
int Search(char *a,char ch)
{//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>ch<63><68><EFBFBD>ڵ<EFBFBD>λ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>±꣬<C2B1><EAA3AC><EFBFBD>򷵻<EFBFBD>-1
for(int i=0;a[i]!='\0';i++){
if(a[i]==ch)return i;
}
return -1;
}
/*
ͳ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD>
freq<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŵ<EFBFBD><EFBFBD><EFBFBD>
letters<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>
*/
int countLetter(char* filename, int *freq, char *letters)
{
ifstream infile(filename);
if(!infile.is_open()){
cerr<<"ifstream open file error\n";
return 0;
}
infile.seekg(0,ios_base::end);
int length = infile.tellg();
infile.seekg(ios_base::beg);
char* buff=new char[length+1]();
infile.read(buff,length+1);
int count=0;
for(int i=0;i<length+1;i++){
// cout<<buff[i];
int x=Search(letters,buff[i]);
if(x==-1){
letters[count++]=buff[i];
letters[count]='\0';
}
x=Search(letters,buff[i]);
freq[x]++;
}
infile.close();
return count-1;
}
int main()
{
HTree htt=NULL;
int freq[128] = {0};
char letters[128] = {'\0'};
int len;
char dec[10000],code[100],zipped[100000];
const char *choe="end",*chob="begin",*choz="zipped",*choc="checktree",*chod="decode",*choo="help";
char s[100];//="C:\\Users\\<5C><>а\\Desktop\\<5C><><EFBFBD><EFBFBD>vc2019\\dev\\hhh.txt";
cout<<"-----------------------------------------"<<endl;
cout<<" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>begin<EFBFBD><EFBFBD>ʼ"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>end<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>zippedչʾѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>checktree<EFBFBD><EFBFBD><EFBFBD>Ҷ<EFBFBD>ӽ<EFBFBD><EFBFBD>Ȩ<EFBFBD>غͱ<EFBFBD><EFBFBD><EFBFBD>"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>decode<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>help<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<<endl;
cout<<"-----------------------------------------"<<endl;
cin>>s;
while(strcmp(s,choe)){
if(strcmp(s,chob)==0){
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>txt<EFBFBD>ļ<EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
cin>>s;
len = countLetter(s, freq, letters);
cout<<"-----------------------------------------"<<endl;
cout<<"<EFBFBD>ַ<EFBFBD>ͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<<len<<"<EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>"<<endl;
ht.elem=new ElemType[len*2-1];
ht.length=0;
input(freq,letters,len);
cout<<"˳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD>"<<endl;
creatHt(htt, len);
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD>"<<endl;
hufEncode(htt, 0, code);
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<<endl;
hufmadecode(s,htt,zipped,len);
cout<<"<EFBFBD>ļ<EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<<endl;
cout<<"-----------------------------------------"<<endl;
}
// seqListInit(ht,len*2-1);
else if(strcmp(s,choz)==0){
cout<<"-----------------------------------------"<<endl;
if(*zipped){
cout<<"ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>"<<endl;
cout<<zipped<<endl;
}
else{
cout<<"<EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>begin<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<<endl;
}
cout<<"-----------------------------------------"<<endl;
}
else if(strcmp(s,choc)==0){
cout<<"-----------------------------------------"<<endl;
if(htt!=NULL){
cout<<"<EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>"<<endl;
printHfTreePre(htt);
}
else{
cout<<"δ<EFBFBD>ҵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>begin<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<<endl;
}
cout<<"-----------------------------------------"<<endl;
}
else if(strcmp(s,chod)==0){
if(*zipped){
cout<<"-----------------------------------------"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>"<<endl;
hufDecode(htt, zipped, dec);
cout<<endl<<"-----------------------------------------"<<endl;
}
else{
cout<<"-----------------------------------------"<<endl;
cout<<"<EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>begin<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<<endl;
cout<<"-----------------------------------------"<<endl;
}
}
else if(strcmp(s,choo)==0){
cout<<"-----------------------------------------"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>begin<EFBFBD><EFBFBD>ʼ"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>end<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>zippedչʾѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>checktree<EFBFBD><EFBFBD><EFBFBD>Ҷ<EFBFBD>ӽ<EFBFBD><EFBFBD>Ȩ<EFBFBD>غͱ<EFBFBD><EFBFBD><EFBFBD>"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>decode<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>help<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<<endl;
cout<<"-----------------------------------------"<<endl;
}
else {
cout<<"-------------------------------------------------"<<endl;
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룡(<28><><EFBFBD><EFBFBD>help<6C><EFBFBD><E9BFB4><EFBFBD><EFBFBD>)"<<endl;
cout<<"-------------------------------------------------"<<endl;
}
cout<<"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ָ<EFBFBD>";
cin>>s;
}
return 0;
}