69,370
社区成员
发帖
与我相关
我的任务
分享
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <vld.h>
#include <string.h>
#define NUM 1000000
//建立哈希表
typedef struct HashTable
{
int num;
int ntimes;
}HashTable;
//创建一个文件,写入100w个随机数
void CreateFile(const char *path)
{
assert(path != NULL);
FILE *fw = fopen(path,"wb");//以二进制写入方式打开(创建)文本文件
srand((unsigned int)time(NULL));
int tmp = 0;
for (int i = 0; i < NUM; i++)
{
tmp = rand();
fwrite(&tmp,sizeof(int),1,fw);//向文件中循环写入100w个随机数
}
fclose(fw);//关闭文件
}
//得到当前哈希文件中出现次数最多的数字
HashTable HashMax(FILE* fp,int divide)
{
int* arr = (int*)calloc(RAND_MAX/divide+1,sizeof(int));//计数器数组
int tmp = 0;
while (fread(&tmp,sizeof(int),1,fp))//当前数字所对应计数器加一
{
arr[tmp/divide]++;
}
HashTable ht = {0};
for (int i = 0; i < RAND_MAX/divide+1; i++)//得到当前文件中出现最多数字及次数
{
if (arr[i] > ht.ntimes)
{
ht.ntimes = arr[i];
ht.num = i*divide + tmp%divide;
}
}
free(arr);
return ht;
}
//若内存不足以创建足够大的计数器
HashTable Search_Million_plus(const char *path,int divide)
{
assert(path != NULL);
assert(divide > 0);
FILE** farr = (FILE**)malloc(divide*sizeof(FILE*));//定义一个文件指针数组
char tmp[200] = "";
for (int i = 0; i < divide; i++)//散列成divide份文件
{
sprintf(tmp,"D://%d.txt",i);
farr[i] = fopen(tmp/*D://i.txt*/,"w+b");
assert(farr[i] != NULL);
}
FILE* fr = fopen(path,"rb");
int num = 0;
while(fread(&num,sizeof(int),1,fr))//将从源文件读取到的数字写入对应的分列文件中
{
int t = num % divide;
fwrite(&num,sizeof(int),1,farr[t]);
}
for (int i = 0; i < divide; i++)//将哈希文件指针移至文件头
{
fseek(farr[i],0,SEEK_SET);
}
HashTable* pht = (HashTable*)malloc(divide*sizeof(HashTable));//建立一个结构体数组保存各哈希文件中出现最多的数
for (int i = 0; i < divide; i++)
{
pht[i] = HashMax(farr[i],divide);
}
HashTable ht = {0};
for (int i = 0; i < divide; i++)//找到出现次数最多的数
{
if (pht[i].ntimes > ht.ntimes)
{
ht.ntimes = pht[i].ntimes;
ht.num = pht[i].num;
}
}
for (int i = 0; i < divide; i++)//关闭文件,释放内存
{
fclose(farr[i]);
sprintf(tmp,"D://%d.txt",i);
remove(tmp);
}
free(farr);
free(pht);
fclose(fr);
return ht;
}
int main()
{
char* path = "D://input.txt";
//CreateFile(path);//创建文件
HashTable ht = Search_Million_plus(path,300);//divide < 509
printf("num = %d, ntimes = %d\n",ht.num,ht.ntimes);
return 0;
}