海量資料處理(查重,topk)

2021-09-13 22:00:23 字數 3432 閱讀 8847

求top k

對記憶體有限制的大資料處理

查重:就是在一組海量資料中,查詢重複的資料,一般的解題思路就是雜湊表

名稱特點

unordered_set

單重集合,只存放key,不允許key重複

unordered_multiset

多重集合,只存放key,允許key重複

unordered_map

單重對映表,存放[key, value]鍵值對,不允許key重複

unordered_multimap

多重對映表,存放[key, value]鍵值對,允許key重複

int

main()

// 用雜湊表解決查重,因為只查重,所以用無序集合解決該問題

unordered_set<

int>

hashset;

for(

int val : vec)

else

}return0;

}

#include 

#include

using namespace std;

intmain()

// 用無序對映表統計數字和數字出現的次數

unordered_map<

int,

int>

hashmap;

for(

int val : vec)

// 列印統計出來的重複的資料

for(pair<

int,

int>

value : hashmap)

} cout << endl;

return0;

}

一、找前top k大的資料用小根堆,找前top k小的資料用大根堆

求vector容器中元素值最大的前10個數字
#include 

#include

#include

#include

using namespace std;

intmain()

// 定義小根堆

priority_queue<

int, vector<

int>

, greater<

int>

> minheap;

// 先往小根堆放入10個元素

int k =0;

for(

; k <10;

++k)

/* 遍歷剩下的元素依次和堆頂元素進行比較,如果比堆頂元素大,

那麼刪除堆頂元素,把當前元素新增到小根堆中,元素遍歷完成,

堆中剩下的10個元素,就是值最大的10個元素

*/for

(; k < vec.

size()

;++k)

}// 列印結果

while

(!minheap.

empty()

) cout << endl;

return0;

}

二、利用快排分割函式

partation函式

int

partation

(vector<

int>

&arr,

int i,

int j)

arr[i]

= k;

return i;

}

int

findnok

(vector<

int>

&arr,

int i,

int j,

int k)

intmain()

cout <<

findnok

(vec,

0, vec.

size()

-1,10

)<< endl;

return0;

}

1.首先將所要計算的資料存進乙個大檔案中

2.由於記憶體限制,檔案中的內容無法一次性載入進記憶體,需要將檔案進行分割

3.將該大檔案分割成每乙個檔案足夠裝載進記憶體的多個小檔案

#include 

#include

#include

#include

using namespace std;

// 大檔案劃分小檔案(雜湊對映)+ 雜湊統計 + 小根堆(快排也可以達到同樣的時間複雜度)

intmain()

;for

(int i =

0; i < file_no;

++i)

// 雜湊對映,把大檔案中的資料,對映到各個小檔案當中

int data;

while

(fread

(&data,4,

1, pf)

>0)

// 因為結果要記錄數字和重複的次數,所以需要打包乙個類型別

struct node

// 為什麼要實現operator>,因為小根堆裡面要比較node物件的大小

bool operator>

(const node &src)

const

int val;

// 表示數字的值

int count;

// 表示數字重複的次數};

// 定義乙個鏈式雜湊表

unordered_map<

int,

int>

nummap;

// 先定義乙個小根堆

priority_queue

, greater

> minheap;

// 分段求解小檔案的top 10大的數字,並求出最終結果

for(

int i =

0; i < file_no;

++i)

int k =0;

auto it = nummap.

begin()

;// 如果堆是空的,先往堆放10個資料

if(minheap.

empty()

)//其實就是當讀第乙個檔案時才會進入該迴圈

}// 把k+1到末尾的元素進行遍歷,和堆頂元素比較

for(

; it != nummap.

end();

++it)

}// 清空雜湊表,進行下乙個小檔案的資料統計

nummap.

clear()

;}// 堆中剩下的就是重複次數最大的前k個

while

(!minheap.

empty()

)return0;

}

海量資料處理 top K

區域性淘汰法 用乙個容器儲存前 10000個數,然後將剩餘的所有數字一一與容器內的最小數字相比,如果所有後續的元素都比容器內的 1000個數還小,那麼容器內的這 10000個數就是最大的 10000個數。如果某一後續元素比容器內的最小數字大,則刪掉容器內最小元素,並將該元素插入容器,最後遍歷完這1億...

海量資料處理 (top K問題)

前兩天面試3面學長問我的這個問題 想說teg的3個面試學長都是好和藹,希望能完成最後一面,各方面原因造成我無比想去鵝場的心已經按捺不住了 這個問題還是建立最小堆比較好一些。先拿10000個數建堆,然後一次新增剩餘元素,如果大於堆頂的數 10000中最小的 將這個數替換堆頂,並調整結構使之仍然是乙個最...

海量資料處理演算法(top K問題)

有乙個1g大小的乙個檔案,裡面每一行是乙個詞,詞的大小不超過16位元組,記憶體限制大小是1m。返回頻數最高的100個詞。1.分治 順序讀檔案中,對於每個詞c,取hash c 2000,然後按照該值存到2000個小檔案中。這樣每個檔案大概是500k左右。如果其中的有的檔案超過了1m大小,還可以按照類似...