2012腾讯一面试题

问题链接…… 

有2.5亿个整数存放在一个文件中,(已知内存容量没有此文件大)如何判断出这个文件中有多少个不相同的数。

 

#include<stdio.h>   
#include<stdlib.h>   
void record(int **p,unsigned int k)  //记录数据文件中读出的数……   
{  
    int i=k/32/5000;    //p[i]   
    int j=(k-i*5000*32)/32;    //p[i][j]   
    int m=k%32;    //p[i][j]的第m位   
    int n=1;    //用1代表数k,0则表示文件数据中没有数k   
  
 n<<=m;    //确定位置,如12,第一个数p[0][0]的第12位为1,33则为第2个数p[0][1]的第33-32位为1,5001则p[1][0]的第1位为1   
    *(*(p+i)+j)|=n;  
}  
void count_int(int *p,int *count)   //统计读出来的不同数的个数……   
{  
    register int i=0;    //寄存器应该会更快……   
    register int j;  
    register int k;  
      
    while(i<5000)    //遍历一指针数组中的5000个元素   
    {  
        j=0;  
        k=1;  
        while(j<32)    //遍历每个整型元素中的32位   
        {  
            if(k&*p)    //如果该位是1说明文件中有这个数,计数加1,0则无……   
                (*count)++;  
            k<<=1;    //继续下一位   
            j++;  
        }  
        p++;    //下一个元素……   
        i++;  
    }      
}  
void main()  
{  
   FILE *fp;  
   register int i=0;  
   unsigned int k=0;    //存放读出数据 ,读出的数可能是整型,要转换成无符号型…… 
   int count=0;    //记录不相同数的个数   
   unsigned int num=4294967295;    //要统计整型数据全部范围所需要的位数……2^32位  
   int memory_size=num/32;    //要分配的内存     
   int *p[26844];    //26844=memory_size/5000+1   
   char data_file[30];   //要打开的数据文件名   
     
   for(;i<memory_size/5000+1;i++)  
       p[i]=calloc(5000,sizeof(int));    //分配堆内存,并初始化,不能一下分配太大的一块,不然会出错,所以我把它分成26844块,每块5000个整型元素   
   printf("\n请输入存放数据的文件路径:");  
   gets(data_file);  
   if((fp=fopen(data_file,"rb"))==NULL)        //打开数据文件   
   {  
        printf("\n文件打开错误!");  
        exit(0);  
   }  
   else  
   {  
        while(!feof(fp))    //如果未到文件尾则继续   
        {              
            fscanf(fp,"%d",&k);    //读出一个整型数据   
            record(p,k);    //把内存p中第k位(bit位)变1   
        }  
   }  
   for(i=0;i<26844;i++)   //遍历指针数组中的所有元素……   
        count_int(p[i],&count);  
   printf("\n共有 %d 个不相同的数!\n",count);  
}  

 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值