鱼C论坛

 找回密码
 立即注册
查看: 2135|回复: 3

[技术交流] 一起来做练习学思路

[复制链接]
发表于 2016-5-28 17:21:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 yundi 于 2016-6-25 14:37 编辑

目录
1. 1个1G大小的txt文件,每行是一条用户记录(用户名,密码,电话...).编写一个程序,按姓名检索文件,要求越快越好。
2. 两个大数相乘

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +5 收起 理由
n0noper + 5 + 5 + 5 热爱鱼C^_^

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-5-28 17:26:30 | 显示全部楼层
本帖最后由 yundi 于 2016-5-28 22:36 编辑

1 . 1个1G大小的txt文件,每行是一条用户记录(用户名,密码,电话...).编写一个程序,按姓名检索文件,要求越快越好。

思路:现在电脑一般都4G内存,不用白不用,把文件全加载到内存,然后在内存中检索。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h> //GetTickCount需要

  4. int main()
  5. {
  6.         char path[] = "C:\\Users\\Administrator\\Desktop\\asdfe.txt";
  7.         FILE * fp = NULL;//文件指针
  8.         char sbuf[100] = {0};//缓存
  9.         int star,end;//计时
  10.         int rowcount = 0;//文件行数
  11.         char **spp = NULL;//指向指针数组
  12.         int i;
  13.         char **tmpp = NULL;//用于遍历指针数组
  14.         int count ;//统计结果
  15.         char flag='y';//控制查询循环
  16.         fp = fopen(path,"r");//打开文件
  17.         if(fp==NULL)
  18.         {
  19.                 return -1;
  20.         }
  21.         star = (int)GetTickCount();//开始计时
  22.         while(!feof(fp))//获取总行数
  23.         {
  24.                 fgets(sbuf,100,fp);
  25.                 rowcount++;
  26.         }
  27.         spp = (char **)malloc(sizeof(char*)*rowcount);//分配保存指针数组的内存空间
  28.         i = rowcount;
  29.         fseek(fp,0,SEEK_SET);//上一次读到文件尾,这里要回到文件头

  30.         //将文件全部加载到内存,避免查询时频繁读取硬盘,提高查询效率
  31.         while(!feof(fp))
  32.         {
  33.                 fgets(sbuf,100,fp);//在文件中读取一行,放到缓存
  34.                 spp[rowcount-i] = (char *)malloc(strlen(sbuf)+1);//申请一段内存,将起始地址保存到指针数组
  35.                 strcpy(spp[rowcount-i],sbuf);//将缓存复制到申请的内存中
  36.                 * ((spp[rowcount-i])+strlen(sbuf)) = '\0';//结尾加字符串结束标志
  37.                 i--;//移动到指针数组的下一位置
  38.         }
  39.         end = (int)GetTickCount();
  40.         printf("载入内存完成!历时%d毫秒\n",end-star);

  41.         //查询代码
  42.         while(flag!='n'&&flag!='N')
  43.         {
  44.                 printf("\n\n请输入姓名:");
  45.                 scanf("%s",sbuf);
  46.                 star = (int)GetTickCount();
  47.                 count = 0;
  48.                 for(tmpp = spp;tmpp<spp+rowcount;tmpp++)
  49.                 {
  50.                         if(strstr(*tmpp,sbuf))
  51.                         {
  52.                                 printf("\n%d行:%s",(tmpp-spp)/sizeof(char*)+1,*tmpp);
  53.                                 count ++;
  54.                         }
  55.                 }
  56.                 end = (int)GetTickCount();
  57.                 printf("\n本次查询历时%d毫秒,共有%d条记录",end - star,count);
  58.                 printf("\n是否继续查询?(y/n)");
  59.                 scanf("%c",&flag);//用来吃掉输入姓名后的回车键
  60.                 scanf("%c",&flag);//第二次才接受到'y' or 'n'
  61.         }
  62.         //关闭文件!
  63.         fclose(fp);
  64.         //释放内存!!!
  65.         for(tmpp = spp;tmpp<spp+rowcount;tmpp++)
  66.         {
  67.                 free(*tmpp);
  68.         }
  69.         free(spp);
  70.         getchar();
  71. }
复制代码

上面是单线程的,如果谁有这样的大文件借我做测试?我就来试试多线程。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-25 14:35:25 | 显示全部楼层
2. 两个大数相乘 。
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. //两大数相乘,返回字符串,例如:
  5. // s1   76789 (i--)
  6. // s2      98 (j--)
  7. char * bigmul(const char * s1, const char * s2)
  8. {
  9.         int len1 = strlen(s1);//下标 0~len1-1
  10.         int len2 = strlen(s2);//下标 0~len2-1
  11.         int len9 = len1 + len2 + 1;//下标 0~len9-2,len9-1
  12.         int i,j,tmp;
  13.         char * rel = NULL;
  14.         char * buf = NULL;
  15.         //1.申请空间
  16.         rel = (char *)malloc(sizeof(char)*len9);//保存最终结果,最后一字节是'\0'
  17.         memset(rel,0,sizeof(char)*len9);
  18.         buf = (char *)malloc(sizeof(char)*len9);//临时存放s2的某一位与s1相乘结果,最后一字节保存每次相乘的进位
  19.         //2.计算
  20.         for(i=len2-1;i>=0;i--)
  21.         {
  22.                 memset(buf,0,sizeof(char)*len9);
  23.                 for(j=len1-1;j>=0;j--) //s2的某一位与s1每位依次相乘
  24.                 {
  25.                         tmp = (s1[j]-'0')*(s2[i]-'0') + buf[len9-1];
  26.                         buf[i+j+1] = tmp % 10;
  27.                         buf[len9-1] = tmp / 10;
  28.                 }
  29.                 buf[i+j+1] = buf[len9-1];
  30.                 for(j=len9-2;j>=0;j--)
  31.                 {
  32.                         rel[j] += buf [j];
  33.                         if(rel[j]>9)
  34.                         {
  35.                                 rel[j] %= 10;
  36.                                 rel[j-1] += 1;
  37.                         }
  38.                 }
  39.         }
  40.         free(buf);
  41.         //3.转为字符
  42.         for(i=0;i<len9-1;i++)
  43.         {
  44.                 rel[i] += '0';
  45.         }
  46.         rel[len9-1] = '\0';

  47.         return rel;
  48. }
  49. void main(void)
  50. {
  51.         char str1[100] = {0};
  52.         char str2[100] = {0};
  53.         char * pstr = NULL;
  54.         scanf("%s%s",str1,str2);
  55.         pstr = bigmul(str1,str2);
  56.         printf("\n%s\n",pstr);
  57.         free(pstr);
  58.         system("pause");
  59. }
复制代码


代码计算过程说明:假设 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 ……如此循环乘完所有位。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-6-28 11:03:20 | 显示全部楼层
学习
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-16 18:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表