哈夫曼文件压缩源文件+头文件
来源:互联网 发布:c语言结构体 编辑:程序博客网 时间:2024/05/02 02:01
#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;
}
char* find(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<0) perror(" 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<0) perror(" 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)<0) perror("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)<0) perror("writecode error!");
if(write(fd2,&t,1)<0) perror("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<0) perror(" 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<0) perror(" 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<0) perror(" 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))<0) perror("write.. error!");
}
}
void uncompressing(char* name)
{
struct _filestate *f = malloc(sizeof(struct _filestate));
int r;
int fdr = open(name,O_RDONLY);
if(fdr<0) perror("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<0) perror("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 0
- 哈夫曼文件压缩源文件+头文件
- 头文件、源文件
- 头文件和源文件
- 头文件和源文件
- 头文件与源文件
- 源文件与头文件
- Emacs 源文件 头文件 切换
- VS头文件 源文件切换
- [ZZ]c++ 头文件 源文件
- C++头文件和源文件
- C++头文件与源文件
- C++头文件和源文件
- 头文件和源文件记录
- 头文件,源文件的关系
- 文件&&头文件&&源文件(C++)
- C++中的头文件和源文件:如何写头文件
- C++中的头文件和源文件:如何写头文件
- C++中的头文件和源文件:如何写头文件
- 【九度OJ】题目1474:矩阵幂 解题报告
- 对spring web启动时IOC源码研究
- 关于localhost404打不开
- 约瑟夫环 C语言 单循环链表
- POJ 2513
- 哈夫曼文件压缩源文件+头文件
- BZOJ 1486 [HNOI2009] 最小圈
- Linux下Git的初步使用指南
- JavaScript学习笔记第二天
- JAVA 泛型
- 北航计算机机试13简单版八皇后
- IFE 斌斌学院(js)
- 排序算法
- URL重写技术