C++実現ハフマン符号化/デコーダ(データ構造)
59948 ワード
ハフマン符号化、復号システムを設計する.ASCII符号化されたテキストファイルの文字をハフマン符号化し、符号化ファイルを生成する.逆に、符号化ファイルを1つのテキストファイルに復号することができる.(1)ファイルから任意の英語の短文(ファイルはASCII符号化、拡張子はtxt)を読み込む.(2)異なる文字が文章に現れる頻度を統計して出力する(スペース、改行、句読点なども文字で処理する).(3)文字周波数に基づいてハフマンツリーを構築し、各文字のハフマン符号化を与える.(4)図形化出力ハフマンツリー、ハフマン符号化;(5)テキストファイルをハフマンツリーで符号化し、圧縮ファイル(符号化ファイル接尾辞名.huf)に格納する(6)ハフマン符号化でファイルを格納し、入力テキストファイルサイズと比較してファイル圧縮率を計算する.(7)を復号し、hufファイルをASCII符号化のtxtファイルに復号し、元のtxtファイルと比較する.[テストデータ]テキストファイルは自分で選択し、少なくとも3000文字を含む.[実装コード]
#include
#include
#include
#include
using namespace std;
struct Node{
public:
Node *right;
Node *left;
char data;
int weight;
int x[100];
};
void InsertionSort(Node*A[],int n){
for(int i=1;i<n;i++){
Node *get=A[i];
int j=i-1;
while(j>=0&&A[j]->weight>get->weight){
A[j+1]=A[j];
j--;
}
A[j+1]=get;
}
}
Node* father(Node*root,Node*son){
Node*temp;
if(root==NULL||son==NULL)
return NULL;
if(root->left==son||root->right==son)
return root;
temp=father(root->left,son);
if(temp!=NULL)
return temp;
else
return father(root->right,son);
}
void preorder(Node*root){
if(root!=NULL) {
cout<<root->weight<<" ";
preorder(root->left);
preorder(root->right);
}
}
void sumlevel(Node*root,int *count,int l){
if(root!=NULL) {
count[l]=count[l]+1;
sumlevel(root->left,count,l+1);
sumlevel(root->right,count,l+1);
}
}
void levelorder(Node*t,int*count){
queue<Node*>q;
int x=0,i=0;
if(t!=NULL){
Node*p;
for(int z=0;z<60;z++){
cout<<" ";
}
cout<<t->data<<"("<<t->weight<<")"<<endl;
x=x+1;
i=i+1;
q.push(t);
while(!q.empty()){
p=q.front();
q.pop();
if(p->left){
for(int z=0;z<60/(i+1);z++) cout<<" ";
cout<<p->left->data<<"("<<p->left->weight<<")";
if(x==count[i]){
cout<<endl;
i++;
x=0;
}
x=x+1;
q.push(p->left);
}
if(p->left){
for(int z=0;z<60/(i);z++) cout<<" ";
cout<<p->right->data<<"("<<p->right->weight<<")";
if(x==count[i]){
cout<<endl;
i++;
x=0;
}
x=x+1;
q.push(p->right);
}
}
}
}
void TreePrint(Node *T,int level)
{
if (T!=NULL) return;
TreePrint(T->right,level+1); // , 1
for (int i=0;i<level;i++) //
{
printf(" ");
}
cout<<T->weight<<endl;
TreePrint(T->left,level+1); // , 1
}
int main(){
//
ifstream file("C:\\Users\\wenjian\\start.txt");
char a;
Node *root1;
int n[128]={0};
int x,i,j,num=0;
while(!file.eof()){
file.get(a);
if(file.fail()) break;
x=a;
n[x]++;
}
for(i=0;i<128;i++){
if(n[i]!=0) num++;
}
Node *m[num],*mm[num];
for(i=0;i<num;i++){
m[i]=new Node;
m[i]->left=NULL;
m[i]->right=NULL;
}
j=0;
for(i=0;i<128;i++){
if(n[i]!=0){
m[j]->data=i;
m[j]->weight=n[i];
j++;
}
}
InsertionSort(m,num);
Node *p1,*p2,*p,*t;
j=0;
for(i=0;i<num;i++){
mm[i]=m[i];
}
for(i=0;i<num-1;i++){
t=new Node;
p1=m[i];
p2=m[i+1];
t->weight=m[i]->weight+m[i+1]->weight;
t->left=p1;
t->right=p2;
p=t;
j=i+2;
while(j<num&&p->weight > m[j]->weight){
m[j-1]=m[j];
j=j+1;
}
m[j-1]=p;
}
root1=m[num-1];
int zz[100];
Node *s,*z;
for(i=0;i<num;i++){
for(int xx=0;xx<100;xx++){
zz[xx]=-1;
}
s=father(root1,mm[i]);
z=mm[i];
j=0;
while(s!=root1){
if(s->left==z){
zz[99-j]=0;
}
if(s->right==z){
zz[99-j]=1;
}
z=s;
s=father(root1,z);
j++;
}
if(s->left==z) zz[99-j]=0;
if(s->right==z) zz[99-j]=1;
x=0;
for(int xx=g0;xx<100;xx++){
if(zz[xx]>-1) x++;
}
for(int xx=0;xx<100;xx++){
zz[xx]=zz[xx+100-x];
}
for(int xx=x;xx<100;xx++){
zz[xx]=-1;
}
for(int xx=0;xx<100;xx++){
mm[i]->x[xx]=zz[xx];
}
}
for(i=0;i<num;i++){
cout<<mm[i]->data<<":"<<mm[i]->weight<<" ";
for(j=0;j<100;j++){
if(mm[i]->x[j]>=0) cout<<mm[i]->x[j];
}
cout<<endl;
}
file.close();
//
ifstream file1("C:\\Users\\wenjian\\start.txt");
//
ofstream putfile("C:\\Users\\daima\\progress.txt");
// .huf
ofstream assicfile("C:\\Users\\wenjian\\assic.huf");
int f=0,o=1,w=0;
while(!file1.eof()){
file1.get(a);
if(file1.fail()) break;
for(i=0;i<num;i++){
if(mm[i]->data==a){
for(j=0;j<100;j++){
o=1;
if(mm[i]->x[j]==-1) break;
putfile<<mm[i]->x[j];
if(f<6){
for(int d=0;d<6-f;d++){
o=2*o;
}
w=mm[i]->x[j]*o+w;
f=f+1;
}
if(f==6){
w=mm[i]->x[j]+w;
f=0;
char ww=w;
assicfile<<ww;
w=0;
}
}
}
}
}
file1.close();
putfile.close();
// ifstream outfile("progress.txt");
// ofstream infile("end.txt"); /
// ,
ifstream outfile("C:\\Users\\daima\\progress.txt");
ofstream infile("C:\\Users\\wenjian\\end.txt");
char y;
while(!outfile.eof()){
if(outfile.fail()) break;
s=root1;
z=s;
while(z->left){
outfile.get(y);
if(y=='0'){
s=z;
z=s->left;
}
if(y=='1'){
s=z;
z=s->right;
}
}
if(outfile.fail()) break;
infile<<z->data;
}
outfile.close();
infile.close();
int sum[20]={0};
sumlevel(root1,sum,0);
levelorder(root1,sum);
int q=1;
for(i=0;i<8;i++){
q=q*2;
if(q>=num) break;
}
int zzz=i+1;
ifstream file2("end.txt");
while(!file2.eof()){
if(file2.fail()) break;
file2.get(a);
for(i=0;i<zzz;i++){
}
if(file2.fail()) break;
}
file2.close();
float g,h;
cout<<" :"<<endl;
cin>>g;
cin>>h;
float hh=h/g;
cout<<" :"<<1-hh<<endl;
}