#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include<math.h>
#include<string.h>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct Item{
char value;
int count;
Item * next;
Item * parent;
Item * left;
Item * right;
char code[30];
};
Item * sort(Item * res){
// cout<<"排序开始"<<endl;
for(Item * i = res -> next;i != NULL;i = i -> next){
for(Item * j = i;j -> next != NULL; j = j -> next){
if(i -> count > j -> next -> count){
swap(i -> count,j -> next -> count);
swap(i -> value,j -> next -> value);
Item *p = i -> parent,*l = i -> left,*r = i -> right;
i -> parent = j -> next -> parent;
i -> left = j -> next -> left;
i -> right = j -> next -> right;
j -> next ->parent = p;
j -> next ->left = l;
j -> next ->right = r;
for(int ii = 0;ii < 30;ii++)
swap(i -> code[ii],j -> next -> code[ii]);
}
}
}
// cout<<"排序结束"<<endl;
return res;
}
Item * readFromFile(char * path){
// cout<<"readFromFile"<<endl;
int a [256] ={0};
char c;
Item * head =(Item*)malloc (sizeof(Item));
Item * aa = head;
FILE * file = fopen(path,"r");
while((c=fgetc(file)) != -1){
a[c]++;
}
for(int i = 0;i <= 255;i++){
if(a[i] != 0){
head -> next = (Item*)malloc (sizeof(Item));
head -> next -> next = NULL;
head -> next -> value = i;
for(int j = 0 ; j < 30 ; j++)
head -> next -> code[j] = ' ';
head -> next -> parent = NULL;
head -> next -> left = NULL;
head -> next -> right = NULL;
head -> next -> count = a[i];
head = head -> next;
}
}
fclose(file);
return sort(aa);
}
void setDecode(Item * item){
// cout<<"setDecode"<<endl;
if(item -> left != NULL){
int i = 0;
for(;i<30;i++){
if(item -> code[i] != ' '){
item -> left -> code[i] = item -> code[i];
}else{
item -> left -> code[i] = '0';
break;
}
}
setDecode(item -> left);
}
if(item -> right != NULL){
int j = 0;
for(;j<30;j++){
if(item -> code[j] != ' '){
item -> right -> code[j] = item -> code[j];
}else{
item -> right -> code[j] = '1';
break;
}
}
setDecode(item -> right);
}
}
void printTree(Item * item,FILE * f,char c){
if(c == item -> value){
for(int i = 0 ; item -> code[i] != ' ' ; i++){
fprintf(f,"%c",item -> code[i]);
}
}
if(item -> left != NULL){
printTree( item -> left,f,c);
}
if(item -> right != NULL){
printTree(item -> right,f,c);
}
}
// 返回树的根节点
Item * getTrees(char * src){
Item * res = readFromFile(src);
Item * var = res -> next;
int i =0;
while(var -> next != NULL){
i++;
Item * a = (Item*)malloc(sizeof(Item));
a -> left = var;
for(int ii=0;ii<30;ii++)
a -> code[ii] = ' ';
a -> right = var -> next;
a -> parent = NULL;
a -> count = var -> count + var -> next -> count;
var -> parent = a;
var -> next -> parent = a;
a -> value = -1;
res -> next = a;
a -> next = var -> next -> next;
var = sort(res) -> next;
}
var -> right -> code[0] = '1';
var -> left -> code[0] = '0';
setDecode(var -> right);
setDecode(var -> left);
return var;
}
// 将文本编码输出到文件
int writeToFile(char * src,char * des){
cout<<"writeToFile"<<endl;
FILE * desF = fopen(des,"wb");
FILE * srcF = fopen(src,"r");
Item * tree = getTrees(src);
char s;
int count = 0 ;
while((s = fgetc(srcF)) != EOF){
count++;
printTree(tree,desF,s);
}
fclose(desF);
fclose(srcF);
return count;
}
// 读取txt文件中的2进制字符按照二进制写入特定文件
void printBitToFile(char * srcP,char * outBits){
cout<<"printBitToFile"<<endl;
FILE * src = fopen(srcP,"r");
FILE * des = fopen(outBits,"wb");
char a = 0,i = 0;
int k = 0;
char c ;
int yy = 0;
int vvv = 0;
while((c = fgetc(src)) != EOF){
if(i == 7){
int flag = 0;
a = a | flag;
i++;
}
if(i == 8){
// 将int写入文件并将i重置为0
fputc(a,des);
if(yy <= 30){
printf("%d
",a);
for(int i = 0 ; i< 8 ;i++)
printf("%d",(a >> i ) & 1);
cout<<endl;
yy++;
}
i = 0;
a = 0;
}
if( i < 7){
int flag;
if(c == '1')
flag = pow(2,i);
else flag = 0;
a = a | flag;
i++;
k++;
}
}
if(i != 0){
fprintf(des,"%c",a);
i = 0;
a = 0;
}
fclose(src);
fclose(des);
}
//读取比特流构造原文件
void getPrimary(char* bit,char * des,int sum){
FILE* srcF = fopen(bit,"rb");
FILE* desF = fopen(des,"w");
unsigned int x = 0;
int cur = 0;
int var;
char c;
Item * node = getTrees("C:\Users\樊晨阳1\Desktop\Solitude.txt");
Item * root = node;
c = fgetc(srcF);
while(feof(srcF) == 0){
for(int i = 0; i < 7 ; i++){
var = (c >> i) & 1;
if(var == 1){
node = node -> right;
}else if(var == 0){
node = node -> left;
}
if(node -> value != -1){
fprintf(desF,"%c",node -> value);
node = root;
cur++;
if(cur == sum)
break;
}
}
if(cur == sum)
break;
c = fgetc(srcF);
}
printf("%d",cur);
fclose(srcF);
fclose(desF);
}
//调试数据
void show(Item * i){
if(i -> value != -1){
cout<<"开始"<<endl;
cout<<"value="<<i -> value<<endl;
int j = 0;
while(i -> code[j] != ' '){
printf("%c ",i -> code[j++]);
}
cout<<endl;
}
if(i -> left != NULL){
show(i -> left);
show(i -> right);
}
}
// 调试数据
void printBIT(){
FILE * ff = fopen("C:\Users\樊晨阳1\Desktop\out.txt","r");
FILE * f = fopen("C:\Users\樊晨阳1\Desktop\outBit.txt","rb");
char c ;
char arr[20] = {0};
int i = 0;
while(i < 20){
fread(arr,1,sizeof(arr)-1,f);
for(int i =0; i< 20 ;i ++){
printf("%d
",arr[i]);
}
memset(arr,0,20);
printf("
");
i++;
}
fclose(ff);
fclose(f);
}
//724362
//724247
int main(int argc, char *argv[]) {
int sum = writeToFile("C:\Users\樊晨阳1\Desktop\Solitude.txt","C:\Users\樊晨阳1\Desktop\out.txt");
cout<<"sum = "<<sum<<endl;
printBitToFile("C:\Users\樊晨阳1\Desktop\out.txt","C:\Users\樊晨阳1\Desktop\outBit.txt");
show(getTrees("C:\Users\樊晨阳1\Desktop\Solitude.txt"));
getPrimary("C:\Users\樊晨阳1\Desktop\outBit.txt","C:\Users\樊晨阳1\Desktop\primary.txt",sum);
// printBIT();
return 0;
}