有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);
}