求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大小,還可以按照類似...