上次我在http://www.cnblogs.com/Philip-Tell-Truth/p/4787067.html这里,稍微讲了一下一种很普通的贪婪的算法,其实这个算法一开始是用来做压缩程序的,就是最著名的Huffman压缩算法
那么这个算法是怎么样的呢,我们知道,我们的字符如果以ASCII的形式表示的话(只算英文和数字),其实就是一堆二进制代码,一个char型字符占一个字节。那么我们想到怎么压缩呢?
因为我们的文档不可能打印那一些不可能出现在屏幕的字符,那么我们完全可以把这些字符去掉,然后制一套我们自己的字符表(二进制对应),不一定是1个字节对应一个字符,我们可以6个位对应一个字符这个样子,这样会对文档有一定的压缩。
然后我们再想,在一篇文档中,每一个字符出现的概率不是相等的,有一些字母会出现很多次,比如a,b,s,这些,而有一些会出现的相对较少比如z,q这些,那么我们可不可以根据这个来压缩文件呢?答案是肯定的,既然我们已经确定了我们要根据概率来压缩文件,我们很自然地就会想到贪婪算法。
我们先来看Fence Repair这一道题,这一道题最后我们是把最小的板占据树的最低空间,同样的,对于出现概率不一的字母,我们也可以给他构建一个这样的生成树(不同深度,分叉不同,对应的二进位的位数和状态(0,1)也会不同)。
比如有一个这样的文档,里面的字符出现的概率对应如下:
a | 000 | 10 | 30 |
e | 001 | 15 | 45 |
i | 010 | 12 | 36 |
s | 011 | 3 | 9 |
t | 100 | 4 | 12 |
space | 101 | 13 | 19 |
newline | 110 | 1 | 3 |
总和 | 174 |
我们在不考虑其出现的概率进行压缩的情况下,我们重新制了一个对应表,那么最后出来的比特率就会降低很多
现在我们尝试用概率结合贪婪算法继续进行压缩,我们知道,如果我们要构建一棵生成树的话,我们可以这样办,出现概率较高的字母,我们给他二进制的位比较少,出现概率比较低的字母,我们给他二进制位比较高,然后这样定义以后我们就会有一个很直观的结论,就是因为出现概率比较高的字母占的比特率会比较低,那么我们的整体占的比特数就会相应的低。这是一种贪婪的思想。
然后我们来想,怎么构建这样的字母表呢?我们知道,由于我们最后写到文件上肯定不能直接写ASCII码,不然我们做这些就没意义了,我们最后是要写比特到上面去的,也就是一堆01010101,那么我们既然只有0,1两种状态,我们就可以想到我们可以用二叉树的形式去构建,我们把字母放在节点上,然后结合成一棵二叉树,我们可以这样规定,如果字母在节点的左边,那么这个字母的下一个二进位就是0,在右边就是1。
那么我们最后就会得到一个二叉树,由于我们是要把出现概率较低的字母放在深度比较低的地方,我们可以先把概率较低的字母先结合起来,然后结合成一个新的节点,然后和其他节点继续结合,有点像修篱笆那题。大概就像下图那样
然后我们就得到了一棵生成树,现在我们就可以给所有的字母重新编码了,那么怎么编码呢?刚才我们说了,出现在比较高的字母他的编码会比较长,在深度比较低的字母编码会比较短(节点往左走相应的二进位就代表0,往右走就代表1)我们很容易就可以得到下面的编码表
a | 001 | 10 | 30 |
e | 01 | 15 | 30 |
i | 10 | 12 | 24 |
s | 00000 | 3 | 15 |
t | 0001 | 4 | 16 |
space | 11 | 13 | 26 |
newline | 00001 | 1 | 5 |
总和 | 146 |
可以看到,最后编码占的总空间更小了,达到了我们压缩的目的。
最后的问题就很简单了,怎么实现这个生成最优编码树呢?我们维护一个堆就可以了,建立完树以后就可以根据字母在树的位置给文件写编码拉!
下面是代码,全实现,有点长
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #define MAX 255//可读字符类型最多为255(相当于散列了) 5 #define UNSIGNED_LONG_32_MAX 4294967296ULL 6 #define SUFFIX ".hfc" 7 8 typedef int Position; 9 typedef struct node 10 { 11 char symbol; 12 int sum; 13 struct node *left, *right; 14 }NODE, *Heap; 15 typedef struct node_list 16 { 17 int weight; 18 int code_gragh[MAX]; 19 }LIST; 20 typedef struct _tree 21 { 22 int sum; 23 char symbol; 24 }Hf_Store; 25 26 //局部函数定义 27 Heap *Read_TextFile(int *,FILE **,Hf_Store **,char []); 28 Heap *Read_PackagedFile(int *, FILE **, Hf_Store **,int *,int *); 29 void Inivilzie_store(int[]); 30 void BulidHeap(Heap *, int); 31 void Percolate_Up(Heap *, int, Position); 32 NODE *DeleteMin(Heap *, int *); 33 NODE *Bulid_Tree(Heap *,const int); 34 void Push_in(NODE *, Heap *, int *); 35 void Unpackged_File_to_File(NODE *, FILE *,const int,const int,char[]); 36 void Write_In_Code_List(NODE *, int *, int[],const int,LIST[]); 37 void Write_in_file(NODE *,FILE *,Hf_Store *,const int,char []); 38 void *Allocate_In_Memory(const int, int *, int *, FILE *, LIST[]); 39 void Destory_Node(NODE *); 40 void Binary_to_ANSCII(NODE *,FILE *, FILE *,const int,const int); 41 void Op_OverFlow(unsigned long[], const int); 42 void Op_LackFlow(unsigned long[], const int); 43 Heap *Put_Array_To_Heap(Hf_Store *, const int); 44 inline void Put_size_to_array(const int, const int,const int, int[]); 45 inline void Put_arrary_to_size(int[],int *,int *,int *,int *); 46 inline void Destroy_Heap_node_and_HfTree(Heap **, Hf_Store **,NODE *); 47 48 void Inivilzie_store(int store[]) 49 { 50 for (int i = 0; i < MAX; i++) store[i] = 0; 51 } 52 53 Heap *Read_TextFile(int *length, FILE **fp, Hf_Store **Hf_Tree, char file_name[261]) 54 { 55 int i, word_sum = 0, tmp, j = 1,_store[MAX]; 56 NODE *tmp_node = NULL; 57 58 Inivilzie_store(_store);//初始化读取数组 59 while (1) 60 { 61 fflush(stdin); 62 printf("请输入文件名 "); 63 scanf("%s", file_name); 64 if ((*fp = fopen(file_name, "r")) == NULL) 65 printf("\a文件不存在,请重新输入\n\n"); 66 else break; 67 } 68 for (;;) 69 { 70 tmp = fgetc(*fp); 71 if (feof(*fp)) break; 72 if (!_store[tmp]) word_sum++; 73 _store[tmp]++; 74 } 75 *length = word_sum; 76 Heap *word_arrary = (Heap *)malloc(sizeof(Heap)*(word_sum + 1));//堆从1位置开始 77 *Hf_Tree = (Hf_Store *)malloc(sizeof(Hf_Store)*word_sum); 78 for (i = 0; i < MAX; i++) 79 if (_store[i]){ 80 tmp_node = (NODE *)malloc(sizeof(NODE)); 81 tmp_node->sum = _store[i]; 82 tmp_node->right = tmp_node->left = NULL; 83 tmp_node->symbol = i; 84 word_arrary[j] = tmp_node; 85 j++; 86 } 87 BulidHeap(word_arrary, *length); 88 for (int i = 0; i < word_sum; i++) 89 { 90 (*Hf_Tree)[i].symbol = (word_arrary[i + 1])->symbol; 91 (*Hf_Tree)[i].sum = (word_arrary[i + 1])->sum; 92 } 93 return word_arrary; 94 } 95 96 Heap *Read_PackagedFile(int *length, FILE **fp, Hf_Store **Hf_Tree,int *sum_byte,int *sum_bit_left,char source_file_name[]) 97 { 98 char file_name[261], *suffix = SUFFIX; 99 int inform[3];//文件头的三个信息 100 int sum_bit, scr_size; 101 102 while (1) 103 { 104 fflush(stdin); 105 printf("请输入你要解压文件的文件名(自动添加后缀.hfc) "); 106 scanf("%s", file_name); 107 strcat(file_name, suffix); 108 if ((*fp = fopen(file_name, "rb")) == NULL)//直接用二进制模式读取 109 printf("\a文件不存在,请重新输入\n\n"); 110 else break; 111 } 112 113 fread(&scr_size, sizeof(int), 1, *fp); 114 fread(source_file_name, sizeof(char), scr_size, *fp); 115 source_file_name[scr_size] = ‘\0‘;//补一个斜杠0 116 printf("\n源文件名字为%s", source_file_name); 117 118 fread(inform, sizeof(int), 3, *fp); 119 Put_arrary_to_size(inform, &sum_bit, sum_byte, sum_bit_left, length); 120 *Hf_Tree = (Hf_Store *)malloc(sizeof(Hf_Store) * (*length)); 121 fread(*Hf_Tree, sizeof(Hf_Store), (*length), *fp); 122 123 Heap *word_arrary = Put_Array_To_Heap(*Hf_Tree, *length); 124 125 return word_arrary; 126 } 127 128 void BulidHeap(Heap *word_arrary, int size)//线性建堆法,不多说 129 { 130 Position i; 131 if (size % 2) for (i = size - 1; i > 1; i -= 2) Percolate_Up(word_arrary, size, i / 2);//如果是奇数 132 else for (i = size; i > 1; i -= 2) Percolate_Up(word_arrary, size, i / 2); 133 } 134 135 void Percolate_Up(Heap *heap, int size, Position i) 136 { 137 Position s1, s2; 138 NODE *tmp = heap[i]; 139 for (; i <= size;) 140 { 141 s1 = 2 * i; s2 = s1 + 1; 142 if (s2 <= size) 143 { 144 if ((*heap[s1]).sum <= (*heap[s2]).sum) 145 { 146 if (tmp->sum > (heap[s1])->sum) { heap[i] = heap[s1]; i = s1; } 147 else break; 148 } 149 else 150 { 151 if (tmp->sum > (heap[s2])->sum){ heap[i] = heap[s2]; i = s2; } 152 else break; 153 } 154 } 155 else 156 { 157 if (s1 <= size) 158 { 159 if (tmp->sum > (heap[s1])->sum) { heap[i] = heap[s1]; i = s1; break; } 160 else break; 161 } 162 else break; 163 } 164 } 165 heap[i] = tmp; 166 } 167 168 NODE *DeleteMin(Heap *heap, int *size)//Floyd算法 169 { 170 Position i = 1, s1, s2, s; 171 NODE *out = heap[1]; 172 NODE *tmp = heap[(*size)--]; 173 for (; i <= *size;) 174 { 175 s1 = 2 * i; s2 = s1 + 1; 176 if (s2 <= *size) 177 { 178 if ((heap[s1])->sum <= (heap[s2])->sum) { heap[i] = heap[s1]; i = s1; } 179 else { heap[i] = heap[s2]; i = s2; } 180 } 181 else 182 { 183 if (s1 <= *size) { heap[i] = heap[s1]; i = s1; break; } 184 else break; 185 } 186 } 187 for (; i > 1;) 188 { 189 if (i % 2 == 1)//注意是这里判断奇偶性 190 { 191 s = (i - 1) / 2; 192 if ((heap[s])->sum > tmp->sum) { heap[i]= heap[s]; i = s; } 193 else break; 194 } 195 else 196 { 197 s = i / 2; 198 if ((heap[s])->sum > tmp->sum) { heap[i] = heap[s]; i = s; } 199 else break; 200 } 201 } 202 heap[i] = tmp; return out; 203 } 204 205 void Push_in(NODE *tmp_new, Heap *heap, int *size) 206 { 207 Position i, s; 208 for (i = ++(*size); i > 1;) 209 { 210 if (i % 2 == 1)//注意是这里判断奇偶性 211 { 212 s = (i - 1) / 2; 213 if ((heap[s])->sum > tmp_new->sum) { heap[i] = heap[s]; i = s; } 214 else break; 215 } 216 else 217 { 218 s = i / 2; 219 if ((heap[s])->sum > tmp_new->sum) { heap[i] = heap[s]; i = s; } 220 else break; 221 } 222 } 223 heap[i] = tmp_new; 224 } 225 226 inline void Put_size_to_array(const int sum_bit, const int sum_byte,const int length,int inform[]) 227 { 228 inform[0] = sum_byte;//文件字节数 229 inform[1] = sum_bit;//文件实际比特数 230 inform[2] = length;//文件堆的大小 231 } 232 233 inline void Destroy_Heap_node_and_HfTree(Heap **Heap, Hf_Store **Hf_Tree,NODE *Thead) 234 { 235 free(*Heap); *Heap = NULL; 236 free(*Hf_Tree); *Hf_Tree = NULL; 237 Destory_Node(Thead); 238 } 239 240 inline void Put_arrary_to_size(int inform[], int *sum_bit, int *sum_byte, int *sum_bit_left, int *length) 241 { 242 *sum_byte = inform[0];//文件字节数 243 *sum_bit = inform[1];//文件实际比特数 244 *length = inform[2];//文件堆的大小 245 *sum_bit_left = (*sum_byte * 32) - (*sum_bit); 246 } 247 248 void Destory_Node(NODE *T) 249 { 250 if (T == NULL) return; 251 252 Destory_Node(T->left); 253 Destory_Node(T->right); 254 free(T); 255 } 256 257 void Op_OverFlow(unsigned long M[],const int length) 258 { 259 int overflow = 0; 260 unsigned long long out_flow; 261 262 for (int i = 0; i < length; i++) 263 { 264 out_flow = (unsigned long long)M[i] << 1; 265 266 if (overflow) { 267 out_flow += 1UL; overflow = 0;//一定要记得归零 268 } 269 if (out_flow >= UNSIGNED_LONG_32_MAX){ 270 out_flow -= UNSIGNED_LONG_32_MAX; 271 M[i] = (unsigned long)out_flow; 272 overflow = 1; 273 } 274 else M[i] = (unsigned long)out_flow; 275 } 276 } 277 278 void Op_LackFlow(unsigned long M[], const int length)//TODO:完成这个函数 279 { 280 unsigned long long lack_flow; 281 282 for (int i = length - 1; i >= 0; i--) 283 { 284 lack_flow = (unsigned long long)M[i] << 1; 285 286 if (lack_flow >= UNSIGNED_LONG_32_MAX) 287 { 288 lack_flow -= UNSIGNED_LONG_32_MAX; 289 M[i] = (unsigned long)lack_flow; 290 if (i != length - 1) 291 M[i + 1] += 1UL; 292 } 293 else M[i] = (unsigned long)lack_flow; 294 } 295 } 296 297 Heap *Put_Array_To_Heap(Hf_Store *Hf_Tree, const int length) 298 { 299 Heap *word_arrary = (Heap *)malloc(sizeof(Heap)*(length + 1));//堆从1位置开始 300 NODE *tmp = NULL;; 301 302 for (int i = 0; i < length; i++) 303 { 304 tmp = (NODE *)malloc(sizeof(NODE)); 305 tmp->left = tmp->right = NULL; 306 tmp->symbol = Hf_Tree[i].symbol; 307 tmp->sum = Hf_Tree[i].sum; 308 word_arrary[i + 1] = tmp; 309 } 310 return word_arrary; 311 }
1 #include "plug.h" 2 3 int main()//Huffman压缩程序 4 { 5 Heap *heap = NULL; NODE *Tree_Heap = NULL; FILE *fp = NULL; Hf_Store *Hf_Tree = NULL; 6 int length; char choice; 7 char source_file_name[261];//文件名长度最多为260 8 9 while (1) 10 { 11 printf("Huffman无损压缩程序-----By Philip 2015.7.20----Version 1.0\n"); 12 printf("====================================================\n"); 13 printf("请输入选项\nY(压缩某文件)\tJ(解压某文件)\tQ(退出程序) "); 14 while (1) 15 { 16 fflush(stdin); 17 scanf("%c", &choice); 18 if (choice == ‘Y‘ || choice == ‘J‘ || choice == ‘Q‘) break; 19 printf("\n\a错误的输入,请重新输入 "); 20 } 21 if (choice == ‘Y‘) 22 { 23 heap = Read_TextFile(&length, &fp, &Hf_Tree, source_file_name); 24 Tree_Heap = Bulid_Tree(heap, length); 25 Write_in_file(Tree_Heap,fp,Hf_Tree,length,source_file_name); 26 Destroy_Heap_node_and_HfTree(&heap, &Hf_Tree, Tree_Heap); 27 system("pause"); 28 } 29 else if (choice == ‘J‘) 30 { 31 int sum_bit_left, sum_byte; 32 33 heap = Read_PackagedFile(&length, &fp, &Hf_Tree, &sum_byte, &sum_bit_left,source_file_name); 34 Tree_Heap = Bulid_Tree(heap, length); 35 Unpackged_File_to_File(Tree_Heap, fp, sum_byte, sum_bit_left,source_file_name); 36 Destroy_Heap_node_and_HfTree(&heap, &Hf_Tree, Tree_Heap); 37 system("pause"); 38 } 39 else break; 40 printf("\n\n\n"); system("cls"); 41 } 42 printf("\n");system("pause");return 0; 43 } 44 45 NODE *Bulid_Tree(Heap *heap,const int size) 46 { 47 int size_tmp = size, i = 0; 48 NODE *tmp1 = NULL, *tmp2 = NULL, *tmp_new = NULL; 49 50 for (; size_tmp > 1;)//不断deleteMin 51 { 52 tmp1 = DeleteMin(heap, &size_tmp); 53 tmp2 = DeleteMin(heap, &size_tmp); 54 55 tmp_new = (NODE *)malloc(sizeof(NODE)); 56 tmp_new->left = tmp1; tmp_new->right = tmp2; tmp_new->symbol = ‘\0‘; 57 tmp_new->sum = tmp1->sum + tmp2->sum; 58 59 Push_in(tmp_new, heap, &size_tmp); 60 } 61 return heap[1]; 62 } 63 64 void Write_in_file(NODE *Thead, FILE *fp, Hf_Store *Hf_Tree, const int length,char source_file_name[]) 65 { 66 int sum_bit = 0, Depth = 0, sum_byte, sum_left, inform[3], code_List[MAX], scr_size = strlen(source_file_name); 67 char *suffix = SUFFIX, out_name[MAX + 1], choice = ‘N‘; 68 FILE *out_fp = NULL; 69 LIST code_Hash[MAX]; 70 71 Write_In_Code_List(Thead, &sum_bit, code_List, Depth, code_Hash); 72 73 void *Memory_Pool = Allocate_In_Memory(sum_bit, &sum_byte, &sum_left, fp, code_Hash); 74 Put_size_to_array(sum_bit, sum_byte, length, inform); 75 76 fclose(fp); fp = NULL;//这个时候可以关闭文件流了 77 78 printf("请输入你要输出的压缩文件的文件名(自动添加后缀.hfc) "); 79 while (choice == ‘N‘) 80 { 81 fflush(stdin); 82 scanf("%s", out_name); 83 strcat(out_name, suffix); 84 85 if ((out_fp = fopen(out_name, "r")) != NULL) 86 { 87 printf("文件已存在,是否覆盖?(Y or N) "); 88 while (1) 89 { 90 fflush(stdin); 91 scanf("%c", &choice); 92 if (choice == ‘Y‘) break; 93 else if (choice == ‘N‘) { printf("请重新指定文件名 "); break; } 94 else printf("你的输入有误,请重新输入 "); 95 fclose(out_fp);//先关掉out_fp 96 } 97 } 98 else break; 99 } 100 printf("%s文件即将被写入\n", out_name); 101 102 if ((out_fp = fopen(out_name, "wb+")) == NULL){ 103 printf("文件写入失败\n"); 104 system("pause"); return; 105 } 106 107 fwrite(&scr_size, sizeof(int), 1, out_fp); 108 fwrite(source_file_name, sizeof(char), scr_size, out_fp); 109 fwrite(inform, sizeof(int), 3, out_fp); 110 fwrite(Hf_Tree, sizeof(Hf_Store), length, out_fp); 111 fwrite(Memory_Pool,sizeof(unsigned long), sum_byte, out_fp); 112 113 printf("对%s写入成功!\n", out_name); 114 115 fclose(out_fp); out_fp = NULL;//记得关文件 116 free(Memory_Pool);//记得释放这个 117 } 118 119 void Write_In_Code_List(NODE *T, int *sum_bit, int code_List[],const int Depth,LIST code_Hash[]) 120 { 121 if (T->symbol != ‘\0‘) 122 { 123 *sum_bit += Depth*T->sum; 124 code_Hash[T->symbol].weight = Depth; 125 for (int i = 0; i < Depth; i++) (code_Hash[T->symbol]).code_gragh[i] = code_List[i]; 126 } 127 else//这里如果不是\0那么一定存在左右节点 128 { 129 code_List[Depth] = 0; 130 Write_In_Code_List(T->left, sum_bit, code_List, Depth + 1,code_Hash); 131 code_List[Depth] = 1; 132 Write_In_Code_List(T->right, sum_bit, code_List, Depth + 1,code_Hash); 133 } 134 } 135 136 void *Allocate_In_Memory(const int sum_bit, int *sum_byte, int *sum_bit_left, FILE *fp, LIST code_Hash[]) 137 { 138 int tmp, i; 139 140 if (!(sum_bit % 32)) *sum_byte = sum_bit / 32; 141 else *sum_byte = sum_bit / 32 + 1;//一个字节等于八位(unsigned long是32个字节-1) 142 *sum_bit_left = (*sum_byte) * 32 - sum_bit; 143 144 unsigned long *Memory_Pool = (unsigned long *)malloc(*sum_byte*sizeof(unsigned long)); 145 memset(Memory_Pool, 0, *sum_byte*sizeof(unsigned long)); 146 Memory_Pool[0] = 1;///记住要把第一个弄成1,不然0放不进去 147 148 fseek(fp, 0L, SEEK_SET);//将指针定位到开头 149 for (; ;) 150 { 151 tmp = fgetc(fp); 152 if (feof(fp)) break; 153 154 for (i = 0; i < code_Hash[tmp].weight; i++) 155 { 156 Op_OverFlow(Memory_Pool,*sum_byte); 157 if ((code_Hash[tmp]).code_gragh[i] == 0) Memory_Pool[0]= Memory_Pool[0] | 0X00;//0的时候就按0 158 else Memory_Pool[0] = Memory_Pool[0] | 0X01; //1的时候按1 159 } 160 } 161 return (void *)Memory_Pool; 162 } 163 164 void Binary_to_ANSCII(NODE *T_head, FILE *fp_source, FILE *fp_out, const int sum_byte, const int sum_bit_left) 165 { 166 int i; 167 NODE *tmp; 168 unsigned long *M = (unsigned long *)malloc(sizeof(unsigned long)*sum_byte);//拿一块大的区域 169 fread(M, sizeof(unsigned long), sum_byte, fp_source);//把数据录入这个区域 170 171 for (i = 0; i < sum_bit_left; i++)//首先去掉最后一个区域的空位数字 172 Op_LackFlow(M, sum_byte); 173 for (i = 0; i < T_head->sum; i++) 174 { 175 for (tmp = T_head; tmp->symbol == ‘\0‘;) 176 { 177 if ((M[sum_byte - 1] & 2147483648UL) == 2147483648UL) tmp = tmp->right;//如果是1那么往左走 178 else tmp = tmp->left; //如果是0往右走 179 Op_LackFlow(M, sum_byte); 180 } 181 fputc(tmp->symbol, fp_out); 182 } 183 free(M); 184 } 185 186 void Unpackged_File_to_File(NODE *T_head, FILE *fp, const int sum_byte, int sum_bit_left,char source_file_name[]) 187 { 188 FILE *out_fp = NULL; 189 char choice = ‘N‘, position[268] = "hfc."; 190 191 printf("输出文件的位置将在本程序所在目录的创建,名称为%s%s\n", position, source_file_name); 192 while (choice == ‘N‘) 193 { 194 strcat(position, source_file_name); 195 if ((out_fp = fopen(position, "r")) != NULL) 196 { 197 printf("文件已存在,是否覆盖?(Y or N) "); 198 while (1) 199 { 200 fflush(stdin); 201 scanf("%c", &choice); 202 if (choice == ‘Y‘) break; 203 else if (choice == ‘N‘) { printf("请重新指定文件名 "); break; } 204 else printf("你的输入有误,请重新输入 "); 205 fclose(out_fp);//先关掉out_fp 206 } 207 if (choice == ‘N‘) 208 { 209 scanf("%s", source_file_name); 210 strcat(position, source_file_name); 211 } 212 } 213 else break; 214 } 215 printf("%s文件即将被写入\n", position); 216 217 if ((out_fp = fopen(position, "w")) == NULL){ 218 printf("文件写入失败\n"); 219 system("pause"); return; 220 } 221 Binary_to_ANSCII(T_head, fp, out_fp,sum_byte,sum_bit_left); 222 223 printf("\n成功写入%s文件!\n\n", position); 224 225 fclose(out_fp); out_fp = NULL; 226 fclose(fp); fp = NULL;//记得关源文件 227 }
最后程序我是写出来了,但是这个程序有几个问题:
1.程序不支持中文,只要代码不在ASCII的都不行,也就是音频压缩这些统统不支持,当然了改也很简单,不过要用到widechar或者unicode编码,我就权当练一下就没改下去了
2.其实不改不是我懒,是因为我觉得这个程序有一个致命的BUG,那就是当程序很大的时候压缩会相当的慢,我觉得瓶颈是在我写入比特位的时候的方法不对,但是我去CSDN问了一下,貌似也没什么人回答我,我也不知道怎么改,还望看到这个帖子的人给我一点启示。。。。感激不尽