本帖最后由 yundi 于 2016-5-28 22:36 编辑
1 . 1个1G大小的txt文件,每行是一条用户记录(用户名,密码,电话...).编写一个程序,按姓名检索文件,要求越快越好。
思路:现在电脑一般都4G内存,不用白不用,把文件全加载到内存,然后在内存中检索。#include <stdio.h>
#include <stdlib.h>
#include <windows.h> //GetTickCount需要
int main()
{
char path[] = "C:\\Users\\Administrator\\Desktop\\asdfe.txt";
FILE * fp = NULL;//文件指针
char sbuf[100] = {0};//缓存
int star,end;//计时
int rowcount = 0;//文件行数
char **spp = NULL;//指向指针数组
int i;
char **tmpp = NULL;//用于遍历指针数组
int count ;//统计结果
char flag='y';//控制查询循环
fp = fopen(path,"r");//打开文件
if(fp==NULL)
{
return -1;
}
star = (int)GetTickCount();//开始计时
while(!feof(fp))//获取总行数
{
fgets(sbuf,100,fp);
rowcount++;
}
spp = (char **)malloc(sizeof(char*)*rowcount);//分配保存指针数组的内存空间
i = rowcount;
fseek(fp,0,SEEK_SET);//上一次读到文件尾,这里要回到文件头
//将文件全部加载到内存,避免查询时频繁读取硬盘,提高查询效率
while(!feof(fp))
{
fgets(sbuf,100,fp);//在文件中读取一行,放到缓存
spp[rowcount-i] = (char *)malloc(strlen(sbuf)+1);//申请一段内存,将起始地址保存到指针数组
strcpy(spp[rowcount-i],sbuf);//将缓存复制到申请的内存中
* ((spp[rowcount-i])+strlen(sbuf)) = '\0';//结尾加字符串结束标志
i--;//移动到指针数组的下一位置
}
end = (int)GetTickCount();
printf("载入内存完成!历时%d毫秒\n",end-star);
//查询代码
while(flag!='n'&&flag!='N')
{
printf("\n\n请输入姓名:");
scanf("%s",sbuf);
star = (int)GetTickCount();
count = 0;
for(tmpp = spp;tmpp<spp+rowcount;tmpp++)
{
if(strstr(*tmpp,sbuf))
{
printf("\n%d行:%s",(tmpp-spp)/sizeof(char*)+1,*tmpp);
count ++;
}
}
end = (int)GetTickCount();
printf("\n本次查询历时%d毫秒,共有%d条记录",end - star,count);
printf("\n是否继续查询?(y/n)");
scanf("%c",&flag);//用来吃掉输入姓名后的回车键
scanf("%c",&flag);//第二次才接受到'y' or 'n'
}
//关闭文件!
fclose(fp);
//释放内存!!!
for(tmpp = spp;tmpp<spp+rowcount;tmpp++)
{
free(*tmpp);
}
free(spp);
getchar();
}
上面是单线程的,如果谁有这样的大文件借我做测试?我就来试试多线程。 |