網站日志中記錄了用戶的IP,找出訪問次數最多的IP。
IP地址最多有2^32=4G種取值可能,所以不能完全加載到內存中。
對於每個小文件,可以構建一個IP作為key,出現次數作為value的hash_map,並記錄當前出現次數最多的1個IP地址。
類似問題:
有一個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個文件進行歸並排序(內排序與外排序相結合)。