一道關於大數據面試題(1)

      大數據時代來臨,現在好多面試都有大數據題目,下面大家一起來看一道大數據題目吧

題:

       文件中產生100000 (十萬)個隨機數字,數字的取值範圍0~32767 , 按如下要求實現,在實現過程中能夠使用的數組最長爲10000 ,個別變量的內存忽略。找到重複次數最多的那個數字(如果有多個,選擇任意一 個)

       乍一看這個題我們可能這個數字龐大難以下手,這個題我的思路就是創建一個長度32767的數組,用數組下標保存出現的數字,用數組中每一個下標的所對應的元素保存該數字出現的次數,(大家有沒有發現這個和我們前幾天學的順序表剛好相似)然後利用循環遍歷數組來比較出現次數最多的那一個,但是題目中給我了限制數組長度爲了10000,我們的32767的長度肯定無法創立,所以面對這種情況我們該怎麼辦呢?他不讓我們建立大數組我們可以建立四個小數組,然後比較出四個中的最大就好了,還有一個問題就是我們應該如何驗證我們所計算出來的數據呢?我們可以就建立一個大小32767的數組和那4個小數組的進行比較,如果我們的結果相同那就證明我們準確,下面我來給大家展示我譜寫的代碼

#include "stdio.h"
#include "stdio.h"
#include "stdlib.h"
#include "assert.h"

#define num 1000000

typedef struct Max
{
	int data;
	int times;
}Max;

void  file(char*path)//建立文件存放數據
{
	FILE *fw=fopen(path,"wb");//wb:打開或者新建一個二進制文件,只允許讀;
	
	assert(fw!=NULL);
	int tmp;
	for(int i=0;i<num;i++)
	{
		tmp=rand();
		fwrite(&tmp,sizeof(int),1,fw);
	}
	fclose(fw);
}
Max verify(char*path)//使用一個大的的數組進行計算,爲了和後面的四個數組的結果進行對比
{
	FILE *fr=fopen(path,"rb");//rb:用讀寫方式打開二進制文件;
	assert(fr!=NULL);

	int *arr=(int*)calloc(RAND_MAX+1,sizeof(int));//RAND_MAX是rand函數返回值剛好是32767,calloc動態數組置0;
	int tmp;
	Max a={0,0};
	while(fread(&tmp,sizeof(int),1,fr)>0)
	{
		arr[tmp]++;//動態數組arr下標保存數字,值代表出現次數;
	}
	for(int i=0;i<RAND_MAX+1;i++)
	{
		if(a.times<arr[i])
		{
			a.times=arr[i];
			a.data=i;
		}
	}
	fclose(fr);
	free(arr);
	return a;
}

Max part(char*path)
{
	int len=RAND_MAX/4+1;
	int *arr=(int*)calloc(len,sizeof(int));
	FILE *fr=fopen(path,"rb");
	
	assert(fr!=NULL);
	
	int tmp;
	Max b={0,0};
	while(fread(&tmp,sizeof(int),1,fr)>0)
	{
		arr[tmp/4]++;//避免數組越界所以/4
	}
	for(int i=0;i<len;i++)
	{
		if(b.times<arr[i])
		{
			b.data=i*4+i%4;//還原除4之前的數字
			b.times=arr[i];
		}
	}
		fclose(fr);
	    free(arr);
	    return b;
}
Max part2(char *path)
{
	char *path1 = "E:\\1.txt";//餘數爲0
	char *path2 = "E:\\2.txt";//餘數爲1
	char *path3 = "E:\\3.txt";//餘數爲2
	char *path4 = "E:\\4.txt";//餘數爲3
	FILE *fr = fopen(path,"rb");
	FILE *fw1 = fopen(path1,"wb");
	FILE *fw2 = fopen(path2,"wb");
	FILE *fw3 = fopen(path3,"wb");
	FILE *fw4 = fopen(path4,"wb");

	assert(fr!=NULL&&fw1!=NULL && fw2!=NULL && fw3!=NULL&&fw4!=NULL);
	
	int tmp;
	while(fread(&tmp,sizeof(int),1,fr) > 0)// 將原文件中的數據散列到4個不同的文件中
	{
		if(tmp%4==0) 
		{
			fwrite(&tmp,sizeof(int),1,fw1);
		}
		else if(tmp%4==1)
		{
			fwrite(&tmp,sizeof(int),1,fw2);
		}
		else if(tmp%4 == 2)
		{
			fwrite(&tmp,sizeof(int),1,fw3);
		}
		else
		{
			fwrite(&tmp,sizeof(int),1,fw4);
		}
	}

	Max arr[4];
	arr[0] = part(path1);
	arr[1] = part(path2);
	arr[2] = part(path3);
	arr[3] = part(path4);

	int max= 0;//保存次數最多的數據的下標
	for(int i=0;i<4;i++)
	{
		if(arr[max].times < arr[i].times)
		{
			max = i;
		}
	}
	fclose(fr);
	fclose(fw1);
	fclose(fw2);
	fclose(fw3);
	fclose(fw4);
	
	return arr[max];
}
int main()
{
	char *path = "E:\\big data.txt";
	file(path);
	Max tmp = verify(path);
	Max tmp2 =part2(path);
	printf("數字是=%d,出現次數=%d\n",tmp.data,tmp.times);
	printf("數字是=%d,出現次數=%d\n",tmp2.data,tmp2.times);

	return 0;
}

大家有沒有覺得其實大數據題也就是紙老虎,就是看起來不好處理,其實也沒那麼困難(當然也有可能是我太聰明。)

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章