哈夫曼文件压缩源文件+头文件

#ifndef  _YASUO_
#define   _YASUO_

int count; //临时变量

/结构体1:字符的出现次数
struct  _symbol{
     char character;
     unsigned  int number;
};
//struct _symbol symbol_list[128];
/结构体2:文件的状态记录
struct  _filestate{
     char symbol_count;
     struct  _symbol symbol_list[ 128];
};

/结构体3:哈夫曼树的结点
struct  _node{
     unsigned  int temp;
     struct  _symbol* symbol;
     struct  _node* left;
     struct  _node* right;
};
typedef  struct  _node _node;

/结构体4:字符的编码字典项
struct  _dictionary_itme{
     struct  _symbol* symbol;
     char coding[ 20];
};
/结构体5:字符的编码字典
struct  _dictionary{
     int count;
     struct  _dictionary_itme itme[ 128];
};

void  init(); //初始化   
void  compressing( char*); //压缩
void  uncompressing(); //解压
void  read_file( char*); //读取文件
_node*  creat_haffman(); //创建哈夫曼树
_node*  creat_node( struct  _symbol*); //创建节点
void  creat_dictionary(_node*); //创建压缩字典
void  coding_file( char*); //编码
void  creat_haffman_coding( char*,_node*); //创建哈夫曼编码
#endif




//==============================================

#include   <stdio.h>
#include   <stdlib.h>
#include   <fcntl.h>
#include   <sys/stat.h>
#include   <string.h>
#include   "yasuo.h"

//变量区

int i =  0;
char* head =  NULL;
struct _filestate filestate;   //结构体2:文件的状态记录
_node** node_list;
_node* root;
struct _dictionary dictionary; //结构体5:字符的编码字典

void  init()
{
     int i;
    count= 0;
     bzero(&filestate,sizeof(filestate));
     bzero(&dictionary,sizeof(dictionary));
}
void  creat_haffman_coding( char* coding,_node* _root)
{
     if(_root-> left== NULL&&_root-> right== NULL)
    {
         strcpy(dictionary. itme[i]. coding,head);
        dictionary. itme[i]. symbol = _root-> symbol;
         //printf("%d.%s %c %d\n",i,dictionary.itme[i].coding,dictionary.itme[i].symbol->character,dictionary.itme[i].symbol->number);
        i++;        
         return;
    }   
     if(_root-> left!= NULL)
    {
        *coding= '0';
         creat_haffman_coding(coding+ 1,_root-> left);
        *coding =  0;
    }
     if(_root-> left!= NULL)
    {
        *coding= '1';
         creat_haffman_coding(coding+ 1,_root-> right);
        *coding =  0;
         return;
    }
}
int g= 0;
void  bianli(_node* node)
{
     if(node ==  NULL) return;
     bianli(node-> left);
     printf( "%d.%d\n",g++,node-> temp);
     bianli(node-> right);
}
void  creat_dictionary(_node* _root)
{
     int i;
    dictionary. count = filestate. symbol_count;
     char coding[ 20] = { 0};
    head = coding;
     //printf("%d \n",dictionary.count);
     creat_haffman_coding(coding,_root);
     return;
}
charfind( char ch)
{
     int i =  0;
     while(i<dictionary. count)
         if(ch==dictionary. itme[i]. symbol-> character)
             return dictionary. itme[i]. coding;
         else i++;
     return  NULL;
}

void  coding_file( char* filename) //将源文件转化为哈弗曼编码
{
     int fd =  open(filename,O_RDONLY);
     if(fd< 0perror( " open error!");
     char filename2[ 20] = { 0};
     sprintf(filename2, "%s.vvei",filename);
     //printf("%s\n",filename2);
     int fd2 =  open(filename2,O_CREAT|O_RDWR);
     if(fd2< 0perror( " open2 error!");
     unsigned  char temp =  0;
     printf( "1.%d\n",sizeof(filestate));
     int r;
    r =  write(fd2,&filestate,sizeof(filestate));
     if(r< 0) perror( " write error!");
     printf( "3.%d\n",r);
     // struct _filestate f;
     // r = read(fd2,&f,sizeof(f));
     // if(r<0)perror("read error!");
     // printf("4.%d\n",r);
     // printf("%d %d\n",f.symbol_count,filestate.symbol_count);

     unsigned  char ch =  0;
     unsigned  char ch1 =  0;
     char* code =  "\0";
     int flag =  0;
     printf( "%d\n",*code);
     int gg= 55;
     while( 1) //将读到的字符转成哈夫曼编码再写到压缩文件中去
    {
         if(flag> 7)
        {   
             if( write(fd2,&ch1, 1)< 0perror( "writecode error!");
             //printf("%d\n%s\n",ch1,code);
            flag =  0;
            ch1 =  0;
             //break;
        }
         if(*code== '0')
        {
            ch1*= 2;
            code+= 1;
            flag++;
        }
         else  if(*code== '1')
        {
            ch1*= 2;
            ch1++;
            code+= 1;
            flag++;
        }
         else  if(*code== 0
        {
             if( read(fd,&ch, 1))
            {
                code =  find(ch);
                 //printf("%c %s\n",ch,code);
            }
             else 
            {
                 char t = flag% 8;
                ch1*=t;
                 if( write(fd2,&ch1, 1)< 0perror( "writecode error!");
                 if( write(fd2,&t, 1)< 0perror( "writecode error!");
                 break;
            }
        }
         else  perror( "code error!");
    }
}
void  read_file( char* filename)
{
     int i =  0;
     int result =  0;
     unsigned  char ch= 0;
     // FILE *f = fopen(filename,"r");
     // if(f==NULL){perror("fopen error!");}
     int fd =  open(filename,O_RDONLY);
     if(fd< 0) { perror( " open error"); return;}
     unsigned  char symbol[ 128] = { 0};
     while(result =  read(fd,&ch, 1))
    {
         if(result< 0)
            { perror( "readfile error!"); return;}
        symbol[ch]++;
    }
     for(i= 0;i< 128;i++)
    {
         if(!symbol[i])
             continue;
        filestate. symbol_list[filestate. symbol_count]. character = i;
        filestate. symbol_list[filestate. symbol_count++]. number = symbol[i];
         //printf("%d. %d %d\n",filestate.symbol_count,filestate.symbol_list[filestate.symbol_count-1].character,filestate.symbol_list[filestate.symbol_count-1].number);
    }
     close(fd);
}
_node*  creat_node( struct _symbol* s)
{
    _node* p;
    p =  malloc(sizeof(_node));
    p-> temp = s-> number;
    p-> symbol = s;
    p-> left =  NULL;
    p-> right =  NULL;
     return p;
}
_node*  creat_haffman( struct _filestate* filestate) //(未用优先队列实现)
{
    _node* parent =  NULL;
     unsigned  char i,j; //临时变量
    node_list = (_node**) malloc(filestate-> symbol_count*sizeof(_node*));
     for(i= 0;i<filestate-> symbol_count;i++)
    {   
        node_list[i] =  creat_node(&(filestate-> symbol_list[i]));
    }
     // printf("===================\n");
     // for(i=0;i<filestate.symbol_count;i++)
     // {    
     //  printf("%d %d %d\n",i,node_list[i]->symbol->character,node_list[i]->temp);
     // }

     unsigned  char minidx =  0;
     unsigned  char secidx =  0;
     for(i= 0;i<filestate-> symbol_count- 1;i++)
    {
        j= 0;
         while(!node_list[j])
        {
            j++;
        }
        minidx = j;
         for(j= 0;j<filestate-> symbol_count;j++)
        {
             if(node_list[j]!= NULL && node_list[j]-> temp < node_list[minidx]-> temp)
                minidx = j;
        }
         //printf("min:%d \n",node_list[minidx]->temp);
        j= 0;
         while(j==minidx || !node_list[j])
        {

            j++;
        }
        secidx = j;
         for(j= 0;j<filestate-> symbol_count;j++)
        {
             if(j!=minidx && node_list[j]!= NULL && node_list[j]-> temp < node_list[secidx]-> temp)
                secidx = j;
        }   
         //printf("sec:%d \n",node_list[secidx]->temp);
        parent =  malloc(sizeof(_node));
        parent-> temp = node_list[minidx]-> temp + node_list[secidx]-> temp;
        parent-> symbol =  NULL;
        parent-> left = node_list[minidx];
        parent-> right = node_list[secidx];
        node_list[minidx] = parent;
        node_list[secidx] =  NULL;
         //secidx = 0;
         // for(j=0;j<filestate.symbol_count;j++)
         // {
         //  if(node_list[j]!=NULL && node_list[j]->temp>node_list[minidx]->temp)
         //      secidx = j;
         // }    
    }
     // int a=0;
     // for(i=0;i<filestate.symbol_count;i++)
     // {
     //  if(node_list[i]!=NULL)a++,printf("%d\n",a);

     // }
     return parent;
}
void  compressing( char* filename)
{
     read_file(filename);
    root =  creat_haffman(&filestate); //创建哈夫曼树
     creat_dictionary(root);
     coding_file(filename); //将源文件转化为哈弗曼编码
     char* s =  find( 'u');
     printf( "%c %s\n", 'u',s);
}
char  findchar(_node* p, int fd, unsigned  char* t, int* f)
{
    (*f)--;
     if(*f< 1)
    {
         int r =  read(fd,t, 4);
         if(r< 0perror( " read error!");
         else  if(r== 0)
        {
             return - 1;
        }
        *f =  8;
    }
     if(p-> left== NULL&&p-> right== NULL)
         return p-> symbol-> character;
     if((*t>>*f)% 2)
             return  findchar(p-> right,fd,t,f);
     else  return  findchar(p-> left,fd,t,f);
}
void  jieya(_node* root, int fdr, int fdw)
{
     unsigned  char temp= 0;
     char ch;
     int flag=- 1;
     int r;
     _node* p =  NULL;
     // unsigned int te=0;
     // int gg=1;
     // char s[34]= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.";
     // int f;
     while( 1)
    {
         if(flag< 0)
        {
            r =  read(fdr,&temp, 1);
             if(r< 0perror( " read error!");
             else  if(r== 0) return;
            flag =  7;
             // te = temp;
             // printf("%d..%d",gg,temp);
             // f = 31;
             // while(f+1)
             // {            
             //  s[f--] = (char)(te%2+48);
             //  te/=2;
             // }
             // printf(" %s\n",s);
        }
         // if((temp>>flag)%2)
         //  ch = findchar(root->right,temp,&flag);
         // else ch = findchar(root->left,temp,&flag);
         //  ch = findchar(root,fdr,&temp,&flag);
        p = root;
         while( 1)
        {
             if(flag< 0)
            {
                r =  read(fdr,&temp, 1);
                 if(r< 0perror( " read error!");
                 else  if(r== 0) return;
                flag =  7;
                 // te = temp;
                 // printf("%d..%d",gg,temp);
                 // f = 31;
                 // while(f+1)
                 // {            
                 //  s[f--] = (char)(te%2+48);
                 //  te/=2;
                 // }
                 // printf(" %s\n",s);
            }
             if(p-> left== NULL&&p-> right== NULL)
            {
                ch =  p-> symbol-> character;
                 //printf(" %c\n",ch);
                 break;
            }
             if((temp>>flag)% 2)
                p = p-> right,flag--;
             else p = p-> left,flag--;
        }
         if(( write(fdw,&ch, 1))< 0perror( "write.. error!"); 
    }
}
void  uncompressing( char* name)
{
     struct _filestate *f =  malloc(sizeof( struct _filestate));
     int r;
     int fdr =  open(name,O_RDONLY);
     if(fdr< 0perror( "openr error!");
     //读取文件头
     if(( read(fdr,f,sizeof( struct _filestate))< 0))  perror( "read error!");
     //创建哈弗曼树
    _node* root =  creat_haffman(f);
     char name2[ 20];
     int len =  strlen(name)- 5;
    name[len] =  0;
     sprintf(name2, "%s.ievv",name);
     printf( "%s\n",name2);
     int fdw =  open(name2,O_CREAT|O_WRONLY);
     if(fdw< 0perror( "openw errorint!");
     //printf("%d\n",fdw);
     //将读压缩文件,创建解压文件
     jieya(root,fdr,fdw);
}

int  main( int argc,  char  const *argv[])
{
     init();
    
     if(argv[ 1][ 0]== '-')
         if(argv[ 1][ 1]== 'y')
             compressing(( char*)argv[ 2]);
         else  if(argv[ 1][ 1]== 'j')
             uncompressing(( char*)argv[ 2]);
     else  printf( "input error\n");
     return  0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值