哈夫曼算法(haffman)实现压缩和解压缩-C语言实现
/*
* =====================================================================================
*
* Filename: haffman.c
*
* Description: huffman coder decoder
*
* Version: 1.0
* Created:
* Revision: none
* Compiler: gcc
*
*
* =====================================================================================
*/ #include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h> #include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h> #define N 256
#define Maxsize 80
#define SOME 1
#define Empty 0
#define FULL -1 typedef unsigned long int WeightType;
typedef unsigned char MyType;
typedef struct //哈夫曼树
{
MyType ch; //存字符
WeightType weight; /* 用来存放各个结点的权值 */
int parent, LChild, RChild; /*指向双亲、孩子结点的指针 */
} HTNode; typedef struct //队列
{
int tag;
int front;
int rear;
MyType length;
char elem[Maxsize];
} SeqQueue; void writeFile();
void printHFM(HTNode * ht, int n);
void code(char **hc, int n, unsigned char *ch); int InitQueue(SeqQueue * Q)
{
if (!Q)
return ;
Q->tag = Empty;
Q->front = Q->rear = ;
Q->length = ; return ;
} int In_seqQueue(SeqQueue * Q, char x)
{
if (Q->front == Q->rear && Q->tag == SOME)
return FULL; //full Q->elem[Q->rear] = x; // printf("in = %c",x);
Q->rear = (Q->rear + ) % Maxsize;
Q->length++;
Q->tag = SOME;
return SOME;
} int Out_Queue(SeqQueue * Q, char *x)
{
if (Q->tag == Empty)
return Empty; *x = Q->elem[Q->front];
Q->length--;
Q->front = (Q->front + ) % Maxsize; if (Q->front == Q->rear)
Q->tag = Empty; return SOME;
} /* ------------------以上是队列的操作------------------------- */ void SelectMinTree(HTNode * ht, int n, int *k)
{
int i, temp;
WeightType min; // printf(" Selecting……n= %d",n);
for (i = ; i <= n; i++) {
if ( == ht[i].parent) {
min = ht[i].weight; //init min
temp = i;
break;
}
}
for (i++; i <= n; i++) {
if ( == ht[i].parent && ht[i].weight < min) {
min = ht[i].weight;
temp = i;
}
}
*k = temp;
} // 对哈夫曼树排序,并统计叶子数量
int SortTree(HTNode * ht)
{
short i, j;
HTNode tmp; for (i = N - ; i >= ; i--) {
for (j = ; j < i; j++)
if (ht[j].weight < ht[j + ].weight) {
tmp = ht[j];
ht[j] = ht[j + ];
ht[j + ] = tmp;
}
}
for (i = ; i < N; i++)
if ( == ht[i].weight)
return i;
return i; //返回叶子个数
} //求哈夫曼0-1字符编码表
char **CrtHuffmanCode(HTNode * ht, short LeafNum)
/*从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码*/
{
char *cd, **hc; //容器
int i, start, p, last; hc = (char **)malloc((LeafNum) * sizeof(char *)); /*分配n个编码的头指针 */ if ( == LeafNum) //只有一个叶子节点时
{
hc[] = (char *)malloc((LeafNum + ) * sizeof(char));
strcpy(hc[], "");
return hc;
} cd = (char *)malloc((LeafNum + ) * sizeof(char)); /*分配求当前编码的工作空间 */
cd[LeafNum] = '\0'; /*从右向左逐位存放编码,首先存放编码结束符 */
for (i = ; i < LeafNum; i++) { /*求n个叶子结点对应的哈夫曼编码 */
start = LeafNum; /*初始化编码起始指针 */
last = i;
for (p = ht[i].parent; p != ; p = ht[p].parent) { /*从叶子到根结点求编码 */
if (ht[p].LChild == last)
cd[--start] = ''; /*左分支标0 */
else
cd[--start] = ''; /*右分支标1 */
last = p;
}
hc[i] = (char *)malloc((LeafNum - start) * sizeof(char)); /*为第i个编码分配空间 */
strcpy(hc[i], &cd[start]);
//
printf("%3d号 %3c 码长:%2d;编码:%s\n", ht[i].ch, ht[i].ch,
LeafNum - start, &cd[start]);
} //getchar();
free(cd); // Printcode(hc,n);
return hc;
} HTNode *CreatHFM(FILE * fp, short *n, WeightType * FileLength)
{
HTNode *ht = NULL;
int i, m, s1, s2;
MyType ch; ht = (HTNode *)malloc( * N * sizeof(HTNode));
if (!ht)
exit(); for (i = ; i < N; i++) {
ht[i].weight = ;
ht[i].ch = (MyType)i; /*1-n号ch 为字符,初始化 */
} for (*FileLength = ; !feof(fp); ++(*FileLength)) {
ch = fgetc(fp); //fread(&ch,1,1,fp);
ht[ch].weight++; //printf("ht[%c].weight= %ld\n",0,ht[0].weight);
}
--(*FileLength); //去掉文件结束后的长度
*n = SortTree(ht);
m = *n * - ; //free(&ht[m+1]);
//printf("叶子个数= %d\n",*n);//getchar();
if ( == *n) {
ht[].parent = ;
return ht;
}
else if ( > *n)
return NULL; for (i = m - ; i >= ; i--) {
ht[i].LChild = ;
ht[i].parent = ;
ht[i].RChild = ;
}
/* ------------初始化完毕!对应算法步骤1--------- */
for (i = *n; i < m; i++) //创建非叶子结点,建哈夫曼树
{ //在ht[0]~ht[i-1]的范围内选择两个parent为0且weight最小的结点,其序号分别赋值给s1、s2返回
SelectMinTree(ht, i - , &s1);
ht[s1].parent = i;
ht[i].LChild = s1; SelectMinTree(ht, i - , &s2);
ht[s2].parent = i;
ht[i].RChild = s2; ht[i].weight = ht[s1].weight + ht[s2].weight;
} /*哈夫曼树建立完毕 */// puts(" over^_^"); return ht;
} //从队列里取8个字符(0、1),转换成一个字节
MyType GetBits(SeqQueue * Q)
{
MyType i, bits = ;
char x; for (i = ; i < ; i++) {
if (Out_Queue(Q, &x) != Empty) { //printf("%c",x);
if ('' == x)
bits = bits << ;
else
bits = (bits << ) | ;
}
else
break;
} //printf(" bits=%d\n",bits);puts(""); return bits;
} //求最长(最短)编码长度
void
MaxMinLength(FILE * File, HTNode * ht, char **hc, short NLeaf, MyType * Max,
MyType * Min)
{
int i;
MyType length; *Max = *Min = strlen(hc[]);
for (i = ; i < NLeaf; i++) {
length = strlen(hc[i]);
fwrite(&ht[i].ch, sizeof(MyType), , File); //字符和对应的
fwrite(&length, sizeof(MyType), , File); //编码长度写进文件
if (length > *Max)
*Max = length;
if (length < *Min)
*Min = length;
}
} //把出现过的字符编码表经过压缩写进文件
short CodeToFile(FILE * fp, char **hc, short n, SeqQueue * Q, MyType * length)
{
int i;
char *p;
MyType j, bits;
short count = ; for (i = ; i < n; i++) // 将n个叶子压缩并写入文件
{
for (p = hc[i]; '\0' != *p; p++)
In_seqQueue(Q, *p); while (Q->length > ) { // puts("出队");
bits = GetBits(Q); //出队8个元素
fputc(bits, fp); //fwrite(&bits,sizeof(char),1,fp);
//printf("压字符 %c\n",bits);
count++;
}
} // printf("码字最后剩: %d\n",Q->length); *length = Q->length;
i = - *length;
bits = GetBits(Q); //取8个如果队不空
for (j = ; j < i; j++)
bits = bits << ; //printf("压 字符 %c\n",bits);
fputc(bits, fp); //fwrite(&bits,sizeof(char),1,fp);
count++; //printf(" 指 针 在%d \n",ftell(fp)); InitQueue(Q);
return count;
} //压缩
void Compress()
{
char desFile[], rename[];
MyType maxLen, minLen, ch, bits, n, finalLength;
int i;
short LeafNum, codeNum;
WeightType count = , Length = , FileLength;
FILE *fp, *compressFile;
SeqQueue *Q;
HTNode *ht = NULL;
char **hc = NULL, **Map = NULL, *p; printf("filename to be compressed:");
scanf("%s", desFile);
//getchar();//fflush(stdin);//清空输入缓冲区域 printf("filename after compressed:");
scanf("%s", rename);
if ('\0' == rename[]) {
printf("输入不能为空,请重新输入:");
scanf("%s", rename);
} compressFile = fopen(rename, "wb");
fp = fopen(desFile, "rb"); //原文件 if (!fp || !compressFile) {
puts("Cannot open file.");
return;
} ht = CreatHFM(fp, &LeafNum, &FileLength); //创建哈夫曼树,统计叶子个数和原文件长度
if (!FileLength) { // printf("文件为空,无须压缩...");
fclose(fp);
fclose(compressFile);
free(ht);
return;
}
Q = (SeqQueue *)malloc(sizeof(SeqQueue));
InitQueue(Q); //SEEK_SET:文件开头 SEEK_CUR:当前位置 SEEK_END:文件结尾
hc = CrtHuffmanCode(ht, LeafNum); //取得哈夫曼0、1编码,hc的长度为LeafNum
//Map为了取编码好定位,再建立全部(256个)//
Map = (char **)malloc(N * sizeof(char *)); //字符编码表
if (!Map) {
puts("申请空间失败");
return;
} for (i = ; i < N; i++) //初始化
Map[i] = NULL; for (i = ; i < LeafNum; i++) // 定位,编码指针数组Map[256]
Map[(int)(ht[i].ch)] = hc[i]; fseek(compressFile, sizeof(WeightType) + sizeof(short) + * sizeof(MyType), SEEK_SET); //先占个位置
//先占个位置,等下填压缩叶子编码剩几个和最长编码长//getchar(); MaxMinLength(compressFile, ht, hc, LeafNum, &maxLen, &minLen); //获得最长码串长度,顺便填写字符对应编码长
// for(i = 0;i < LeafNum;i++)
// if(ht[i].ch == (MyType)1)
// printf("char %c %s\n",ht[i].ch,hc[i]); free(ht); //getchar();printf("最长码串长度: %d\n",MaxCode);printf("ftell = %d\n",ftell(compressFile));
codeNum = CodeToFile(compressFile, hc, LeafNum, Q, &finalLength); //把字符转成其二进制编码写入文件,返回压成多少个 rewind(compressFile); //使文件指针移到开始printf("ftelll = %d\n",ftell(compressFile));
fseek(compressFile, sizeof(WeightType) + sizeof(MyType), SEEK_SET);
fwrite(&LeafNum, sizeof(short), , compressFile); //写入叶子个数
fwrite(&maxLen, sizeof(MyType), , compressFile); //最长码串长度
fwrite(&minLen, sizeof(MyType), , compressFile); //最短码串长度
//printf("MaxLen %d Min %d ftell = %d\n",maxLen,minLen,ftell(compressFile));getchar();
fwrite(&codeNum, sizeof(short), , compressFile); //填写叶子编码压多少个
fwrite(&finalLength, sizeof(MyType), , compressFile); //最后剩
//printf("叶子共压:%d个,最后剩%d个\n\n",codeNum,finalLength); fseek(compressFile, * LeafNum * sizeof(MyType) + codeNum, SEEK_CUR);
//printf("开始正文ftell= %d 原文长%d\n",ftell(compressFile),FileLength);getchar();
fseek(fp, , SEEK_SET);
printf("Please wait a minute,compressing..."); while (count < FileLength) {
ch = fgetc(fp); //fread(&ch,sizeof(MyType),1,fp);
++count; // printf("Read读 : %c 值 %d %s\n",ch,ch,Map[ch]);
for (p = Map[ch]; *p != '\0'; p++)
In_seqQueue(Q, *p);
//printf("\nQlength: %d\n",Q->length); while (Q->length > ) // printf("OutQueue: ");
{
bits = GetBits(Q); //出队8个元素,合成一个字节
fputc(bits, compressFile); //fwrite(&bits,1,1,compressFile);
Length++; // printf("压:%c\n",bits);
}
} //end of while
//最后一个bits ;
finalLength = Q->length; //printf("最后剩Qlength:%d\n",Q->length);
n = - finalLength;
bits = GetBits(Q);
//printf("最后Qlength:%d\n",Q->length);
for (i = ; i < n; i++)
bits = bits << ; //以‘0’补
//fputc(bits,compressFile);
fwrite(&bits, sizeof(MyType), , compressFile); //printf("\nfinal压:%c\n",bits);
Length++; rewind(compressFile); //原文件长fwrite(&FileLength,sizeof(WeightType),1,compressFile);
fwrite(&Length, sizeof(WeightType), , compressFile); //压缩后的长
fwrite(&finalLength, sizeof(char), , compressFile); //最后的串长 Length = Length + + codeNum; //printf("原文件长 %ld;压缩后 %ld\n",FileLength,Length); if (Length >= FileLength)
puts("\nCompression rate: 0.0%");
else
printf("\nCompression rate: %.2lf%c\n",
(double)((FileLength -
Length) / (double)FileLength) * 100.0, '%'); fclose(fp);
fclose(compressFile);
free(Q);
free(hc);
free(Map);
} //把读出的字符,转换成8个0、1字符串并入队
void ToQueue(SeqQueue * Q, MyType ch)
{
int i;
MyType temp; for (i = ; i < ; i++) {
temp = ch << i;
temp = temp >> ;
if ( == temp)
In_seqQueue(Q, ''); //printf("1");
else
In_seqQueue(Q, ''); //printf("0");
} //puts("");
} //解压缩
void UnCompress()
{
MyType *str, MaxLength, MinLength, ch, *num, finalLength = , final = ;
FILE *cf, *uf;
short NLeaf, Ncom;
char CName[N], UName[N], **hc, *p, x, *buf;
SeqQueue *Q = NULL;
int i, j;
WeightType srcLen = , thisFile = ; fflush(stdin); //清空输入缓冲区域
printf("filename to be uncompressed:");
scanf("%s", CName);
if (CName[] == '\0') {
printf("try again:");
scanf("%s", CName);
fflush(stdin);
}
fflush(stdin); //清空输入缓冲区域
printf("filename after uncompressed:");
scanf("%s", UName);
if (UName[] == '\0') {
printf("try again:");
scanf("%s", UName);
} cf = fopen(CName, "rb");
uf = fopen(UName, "wb");
if (!cf || !uf) {
puts("Cannot open files.");
return;
} fread(&srcLen, sizeof(WeightType), , cf); //printf("压后文件长:%ld\n",srcLen);
fread(&finalLength, , , cf); // printf("原文件压剩:%d个\n",finalLength);
fread(&NLeaf, sizeof(short), , cf); //printf("叶子:%d个\n",NLeaf);
fread(&MaxLength, sizeof(MyType), , cf);
fread(&MinLength, sizeof(MyType), , cf);
//printf("MaxLength = %d;minLen= %d,Leaf= %d\n",MaxLength,MinLength,NLeaf);getchar();
Q = (SeqQueue *)malloc(sizeof(SeqQueue)); buf = (char *)malloc(( + MaxLength * sizeof(char)));
str = (MyType *)malloc(NLeaf * sizeof(MyType));
num = (MyType *)malloc(NLeaf * sizeof(MyType));
//压缩叶子数量x和最后剩长
if (!Q || !str || !num || !buf) {
puts("Memery error.");
exit();
}
InitQueue(Q); //初始化 fread(&Ncom, sizeof(short), , cf);
fread(&final, sizeof(MyType), , cf); for (i = ; i < NLeaf; i++) //读取叶子及其码长
{
fread(&str[i], sizeof(MyType), , cf);
fread(&num[i], sizeof(MyType), , cf);
//printf("chars= %c;num= %d\n",Chars[i],CHlength[i]);
}
//printf("read ftell= %d\n",ftell(cf));//getchar();
// printf("\n叶子码字压缩后%d个,最后剩%d个\n",Ncom,final); hc = (char **)malloc((NLeaf) * sizeof(char *)); //hc为编码表的指针数组
if (!hc)
exit(); --Ncom; //printf("开始取叶子编码ftell = %d Ncom=%d\n",ftell(cf),Ncom);
for (j = i = ; i < Ncom; i++) {
ch = fgetc(cf); //fread(&ch,1,1,cf);
ToQueue(Q, ch); //printf("Q->Len= %d\n",Q->length);
while (Q->length > MaxLength) {
hc[j] = p = (char *)malloc( + num[j]);
for (ch = ; ch < num[j]; ch++) {
Out_Queue(Q, &x);
*p++ = x;
}
*p = '\0'; //printf("%c编 码%s\n",str[j],hc[j]);
j++;
}
}
ch = fgetc(cf); //fread(&ch,1,1,cf);//最后一个
ToQueue(Q, ch);
final = - final;
while (Q->length > final) {
p = hc[j] = (char *)malloc( + num[j]);
for (ch = ; ch < num[j]; ch++) {
Out_Queue(Q, &x);
*p++ = x;
}
*p = '\0'; //printf("%c编码%s\n",str[j],hc[j]);getchar();
j++;
} InitQueue(Q);
--srcLen;
--MinLength;
//printf("开始解压正文%d ,压后长= %d\n",ftell(cf),srcLen);getchar();
printf("Please wait a minute,uncompressing...");
while (thisFile < srcLen) {
// printf("QLength= %d\n",Q->length);
ch = fgetc(cf); //fread(&ch,sizeof(MyType),1,cf);
ToQueue(Q, ch);
thisFile++; // printf("char:%c",ch);
//完了后队列长于码串的最大值 while (Q->length > MaxLength) {
for (i = ; i < MinLength; i++) {
Out_Queue(Q, &x);
buf[i] = x;
}
for (; i < MaxLength; i++) {
Out_Queue(Q, &x);
buf[i] = x;
buf[i + ] = '\0';
for (j = ; j < NLeaf; j++) {
if (i + == num[j]
&& == strcmp(hc[j], buf)) {
ch = str[j]; //printf("出队 %s\n",buf);
fputc(ch, uf); //fwrite(&ch,1,1,uf);////printf("解 出:%c\n",ch);
break;
}
}
if (j < NLeaf)
break;
}
} //while MaxLength
} ch = fgetc(cf); //fread(&ch,1,1,cf);//读取最后一个压缩字getchar();
ToQueue(Q, ch); finalLength = - finalLength;
while (Q->length > finalLength) {
for (i = ; i < MinLength; i++) {
Out_Queue(Q, &x);
buf[i] = x;
}
for (; i < MaxLength; i++) {
Out_Queue(Q, &x);
buf[i] = x;
buf[i + ] = '\0';
for (j = ; j < NLeaf; j++) {
if (i + == num[j] && == strcmp(hc[j], buf)) {
ch = str[j]; //printf("出 %s\n",buf);
fputc(ch, uf); //fwrite(&ch,1,1,uf);//printf("解 出:%c\n",ch);
break;
}
}
if (j < NLeaf)
break;
}
}
//printf("Q->length= %d\n",Q->length);printf("ftell= %d\n",ftell(uf));
free(Q);
free(str);
free(num);
free(hc);
fclose(uf);
fclose(cf);
} int main(int argc, char *argv[])
{
char choice, blank[] = " ";
// writeFile();
system("color 8a");
while () {
system("clear"); //清屏
puts(" * * * *Welcome use huffman encoder\\decoder* * *");
puts(" **********************^_^***********************");
puts(" * *");
printf(" * %s 1 ]. Compress %s*\n", blank, blank);
puts(" * *");
printf(" * %s 2 ]. Uncompress%s *\n", blank, blank);
puts(" * *");
printf(" * %s 3 ]. Exit ^_^ %s *\n", blank, blank);
puts(" * *");
puts(" ************************************************");
printf
(" (Apply to text file) Copyright 2011 By Bocai\n");
printf(" Choose (1 to 3):");
choice = getchar(); puts("");
getchar();
fflush(stdin); //清空输入缓冲区域,否则键入的回车符将作为程序结尾处的scanf输入,此函数在stdio.h中
switch (choice) {
case '':
Compress();
printf("Press Enter to continue...");
getchar();
break;
case '':
UnCompress();
printf("\nPress Enter to continue...");
getchar();
break;
case '':
return ;
break;
}
} return ;
} /*----------------------------END----------------------------------------*/
哈夫曼算法(haffman)实现压缩和解压缩-C语言实现的更多相关文章
- 经典贪心算法(哈夫曼算法,Dijstra单源最短路径算法,最小费用最大流)
哈夫曼编码与哈夫曼算法 哈弗曼编码的目的是,如何用更短的bit来编码数据. 通过变长编码压缩编码长度.我们知道普通的编码都是定长的,比如常用的ASCII编码,每个字符都是8个bit.但在很多情况下,数 ...
- 重新想象 Windows 8 Store Apps (70) - 其它: 文件压缩和解压缩, 与 Windows 商店相关的操作, app 与 web, 几个 Core 的应用, 页面的生命周期和程序的生命周期
[源码下载] 重新想象 Windows 8 Store Apps (70) - 其它: 文件压缩和解压缩, 与 Windows 商店相关的操作, app 与 web, 几个 Core 的应用, 页面的 ...
- Java对zip格式压缩和解压缩
Java对zip格式压缩和解压缩 通过使用java的相关类可以实现对文件或文件夹的压缩,以及对压缩文件的解压. 1.1 ZIP和GZIP的区别 gzip是一种文件压缩工具(或该压缩工具产生的压缩文件格 ...
- Linux关于压缩和解压缩实例
在谈到压缩和解压缩,我想说说它们的应用场景,其实它们主要的应用场景是有这么几个方面? (1)备份(几十个数据库每天进行备份,即包含数据又包含脚本,还有其他十分重要的日志文件等等); (2)降低服务器存 ...
- C#压缩和解压缩字节(GZip)
标题:C#压缩和解压缩字节(GZip的使用) 作用:此类在 .NET Framework 2.0 版中是新增的.提供用于压缩和解压缩流的方法和属性.定义:表示 GZip 数据格式,它使用无损压缩和解压 ...
- 『学了就忘』Linux基础命令 — 32、压缩和解压缩相关命令
目录 1.".zip"格式压缩 2.".gz"格式压缩 3.".bz2"格式压缩 4.".tar"格式打包 5.打包和压 ...
- Linux下的压缩和解压缩命令——gzip/gunzip
gzip命令 gzip命令用来压缩文件.gzip是个使用广泛的压缩程序,文件经它压缩过后,其名称后面会多处".gz"扩展名. gzip是在Linux系统中经常使用的一个对文件进行压 ...
- Linux常用命令学习3---(文件的压缩和解压缩命令zip unzip tar、关机和重启命令shutdown reboot……)
1.压缩和解压缩命令 常用压缩格式:.zip..gz..bz2..tar.gz..tar.bz2..rar .zip格式压缩和解压缩命令 zip 压缩文件名 源文件:压缩文件 ...
- [Java 基础] 使用java.util.zip包压缩和解压缩文件
reference : http://www.open-open.com/lib/view/open1381641653833.html Java API中的import java.util.zip ...
- 关于webservice大数据量传输时的压缩和解压缩
当访问WebSerivice时,如果数据量很大,传输数据时就会很慢.为了提高速度,我们就会想到对数据进行压缩.首先我们来分析一下. 当在webserice中传输数据时,一般都采用Dataset进行数据 ...
随机推荐
- ASP.NET Web API从注释生成帮助文档
默认情况下,ASP.NET Web API不从Controller的注释中生成帮助文档.如果要将注释作为Web API帮助文档的一部分,比如在帮助文档的Description栏目中显示方法注释中的su ...
- 设计模式之美:Facade(外观)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):用抽象类定义 Facade 而使子类对应于不同的子系统. 意图 为子系统中的一组接口提供一个一致的界面,Facade 模式定义了 ...
- 为什么要设置getter和setter?
面向对象语言中,通常把属性设置为私有,然后添加getter和setter方法来访问.有人说,这本质上和设置属性为公有没有区别,干脆把属性public算了.也有人反驳,这样做破坏了封装.但是,破坏了封装 ...
- C++数组和指针
<C++ Primer 4th>读书摘要 与 vector 类型相似,数组也可以保存某种类型的一组对象:而它们的区别在于,数组的长度是固定的.数组一经创建,就不允许添加新的元素.指针则可以 ...
- paip.日期时间操作以及时间戳uapi php java python 总结
paip.日期时间操作以及时间戳uapi php java python 总结 ///uapi Date 函数 | Day 函数 | Hour 函数 | Minute 函数 | Month 函数 | ...
- Java性能提示(全)
http://www.onjava.com/pub/a/onjava/2001/05/30/optimization.htmlComparing the performance of LinkedLi ...
- malloc钩子和内存泄漏工具mtrace、Valgrind
一:malloc钩子函数 static void* (* old_malloc_hook) (size_t,const void *);static void (* old_free_hook)(vo ...
- 一道SQL面试例题 if...else 与聚集函数
晚上回来,同学说面试遇到了一个SQL面试题目,自己做了一下,总结总结. 题目如下: 下面是产品数据表(产品id,颜色col,数量num),其中每种产品有1~2种颜色. 求每种产品各颜色的数量差值(对于 ...
- ES5 数组方法map
概述 map() 方法返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组. 语法 array.map(callback[, thisArg]) 参数 callback 原数组中的元素经 ...
- C#中将结构类型数据存储到二进制文件中方法
以往在vb6,vc6中都有现成的方法将结构类型数据写入和读取到二进制文件中,但是在c#中却没有现成的方法来实现,因此我查阅了一些资料,借鉴了网上一些同学的做法,自己写了个类似的例子来读写结构类型数据到 ...