1. 程式人生 > >從一億個ip找出出現次數最多的IP(分治法)

從一億個ip找出出現次數最多的IP(分治法)

/*
1,hash雜湊
2,找到每個塊出現次數最多的(默認出現均勻)—–>可以用字典樹
3,在每個塊出現最多的資料中挑選出最大的為結果
*/

問題一:
怎麼在海量資料中找出重複次數最多的一個
演算法思想:
方案1:先做hash,然後求模對映為小檔案,求出每個小檔案中重複次數最多的一個,並記錄重複次數。
然後找出上一步求出的資料中重複次數最多的一個就是所求(如下)。

問題二:
網站日誌中記錄了使用者的IP,找出訪問次數最多的IP。
演算法思想:
IP地址最多有2^32=4G種取值可能,所以不能完全載入到記憶體中。
可以考慮分而治之的策略;
map
按照IP地址的hash(IP)%1024值,將海量日誌儲存到1024個小檔案中,每個小檔案最多包含4M個IP地址。
reduce
對於每個小檔案,可以構建一個IP作為key,出現次數作為value的hash_map,並記錄當前出現次數最多的1個IP地址。
有了1024個小檔案中的出現次數最多的IP,我們就可以輕鬆得到總體上出現次數最多的IP。

同樣的問題:
假設有1kw個身份證號,以及他們對應的資料。身份證號可能重複,要求找出出現次數最多的身份證號。

補充問題:
如果是要找出前k個最大的呢?

類似問題:

   有一個1G大小的一個檔案,裡面每一行是一個詞,詞的大小不超過16位元組,記憶體限制大小是1M。返回頻數最高的100個詞。

演算法思想:

第一步、順序讀檔案中,對於每個詞x,取,然後按照該值存到5000個小檔案(記為)中。這樣每個檔案大概是200k左右。如果其中的有的檔案超過了1M大小,還可以按照類似的方法繼續往下分,直到分解得到的小檔案的大小都不超過1M。

(第一步結束後,相同內容的詞在同一個檔案中,且檔案比較小)

對每個小檔案,統計每個檔案中出現的詞以及相應的頻率(可以採用trie樹/hash_map等),並取出出現頻率最大的100個詞(可以用含100個結點的最小堆),並把100詞及相應的頻率存入檔案,這樣又得到了5000個檔案。下一步就是把這5000個檔案進行歸併(類似與歸併排序)的過程了。

類似問題:

    有10個檔案,每個檔案1G,每個檔案的每一行存放的都是使用者的query,每個檔案的query都可能重複。要求你按照query的頻度排序。

演算法思想:

順序讀取10個檔案,按照hash(query)%10的結果將query寫入到另外10個檔案(記為)中。這樣新生成的檔案每個的大小大約也1G(假設hash函式是隨機的)。
找一臺記憶體在2G左右的機器,依次對用hash_map(query, query_count)來統計每個query出現的次數。利用快速/堆/歸併排序按照出現次數進行排序。將排序好的query和對應的query_cout輸出到檔案中。這樣得到了10個排好序的檔案(b0,b1,b2,…,b9)。
對(b0,b1,b2..,b9)這10個檔案進行歸併排序(內排序與外排序相結合)。