一起来做练习学思路
本帖最后由 yundi 于 2016-6-25 14:37 编辑目录
1. 1个1G大小的txt文件,每行是一条用户记录(用户名,密码,电话...).编写一个程序,按姓名检索文件,要求越快越好。
2. 两个大数相乘 本帖最后由 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 = {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 = (char *)malloc(strlen(sbuf)+1);//申请一段内存,将起始地址保存到指针数组
strcpy(spp,sbuf);//将缓存复制到申请的内存中
* ((spp)+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();
}
上面是单线程的,如果谁有这样的大文件借我做测试?我就来试试多线程。{:5_108:} 2. 两个大数相乘 。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//两大数相乘,返回字符串,例如:
// s1 76789 (i--)
// s2 98 (j--)
char * bigmul(const char * s1, const char * s2)
{
int len1 = strlen(s1);//下标 0~len1-1
int len2 = strlen(s2);//下标 0~len2-1
int len9 = len1 + len2 + 1;//下标 0~len9-2,len9-1
int i,j,tmp;
char * rel = NULL;
char * buf = NULL;
//1.申请空间
rel = (char *)malloc(sizeof(char)*len9);//保存最终结果,最后一字节是'\0'
memset(rel,0,sizeof(char)*len9);
buf = (char *)malloc(sizeof(char)*len9);//临时存放s2的某一位与s1相乘结果,最后一字节保存每次相乘的进位
//2.计算
for(i=len2-1;i>=0;i--)
{
memset(buf,0,sizeof(char)*len9);
for(j=len1-1;j>=0;j--) //s2的某一位与s1每位依次相乘
{
tmp = (s1-'0')*(s2-'0') + buf;
buf = tmp % 10;
buf = tmp / 10;
}
buf = buf;
for(j=len9-2;j>=0;j--)
{
rel += buf ;
if(rel>9)
{
rel %= 10;
rel += 1;
}
}
}
free(buf);
//3.转为字符
for(i=0;i<len9-1;i++)
{
rel += '0';
}
rel = '\0';
return rel;
}
void main(void)
{
char str1 = {0};
char str2 = {0};
char * pstr = NULL;
scanf("%s%s",str1,str2);
pstr = bigmul(str1,str2);
printf("\n%s\n",pstr);
free(pstr);
system("pause");
}
代码计算过程说明:假设 s1是76789 (i--),s2是 98 (j--),i递减表示s1从个位到最高位,j表示s2从个位到最高位。先用s2个位8乘 s1,8*9=72,2存到buf,7存到buf最后一字节;再8*8(s1的十位)=64,64+刚才的进位7=71,1存到buf,又有进位7存到buf最后一字节;直到8*s1最高位,这时buf结果是76789*8=614312。把本轮结果放到rel中,然后进行第二轮,即s2的十位9依次乘s1,结果76789*9=691101存到buf,再把buf累加到rel ……如此循环乘完所有位。
学习
页:
[1]