或者如下闡述(雪域之鷹):
演算法思想:分而治之+hash
(1)ip 位址最多有2^32=4g種取值情況,所以不能完全載入到記憶體中處理;
(2)可以考慮採用「分而治之」的思想,按照ip位址的hash(ip)%1024值,把海量ip日誌分別儲存到1024個小檔案中。這樣,每個小檔案最多包含4mb個ip位址;
(3)對於每乙個小檔案,可以構建乙個ip為 key,出現次數為value的hash map,同時記錄當前出現次數最多的那個ip位址;
(4)可以得到1024個小檔案中的出現次數最多的ip,再依據常規的排序演算法得到總體上出現次數最多的ip;
假設目前有一千萬個記錄(這些查詢串的重複度比較高,雖然總數是1千萬,但如果除去重複後,不超過3百萬個。乙個查詢串的重複度越高,說明查詢它的使用者越多,也就是越熱門。),請你統計最熱門的10個查詢串,要求使用的記憶體不能超過1g。
第一步、先對這批海量資料預處理,在o(n)的時間內用hash表完成統計(之前寫成了排序,特此訂正。july、2011.04.27);
第二步、借助堆這個資料結構,找出 top k,時間複雜度為 n『logk。即,借助堆結構,我們可以在log量級的時間內查詢和調整/移動。因此,維護乙個k(該題目中是 10)大小的小根堆,然後遍歷300萬的query,分別和根元素進行對比所以,我們最終的時間複雜度是:o(n) + n』*o(logk),(n 為 1000 萬,n』為 300 萬)。ok,更多,詳情,請參考原文。
或者:採用 trie 樹,關鍵字域存該查詢串出現的次數,沒有出現為 0。最後用 10 個元素的最小推來對出現頻率進行排序。
方案:順序讀檔案中,對於每個詞 x,取 hash(x)%5000,然後按照該值存到 5000 個小檔案(記為 x0,x1,…x4999)中。這樣每個檔案大概是 200k 左右。
如果其中的有的檔案超過了1m 大小,還可以按照類似的方法繼續往下分,直到分解得到的小檔案的大小都不超過1m。
對每個小檔案,統計每個檔案中出現的詞以及相應的頻率(可以採用 trie 樹/hash_map 等),並取出出現頻率最大的100個詞(可以用含100個結點的最小堆),並把100個詞及相應的頻率存入檔案,這樣又得到了5000個檔案。下一步就是把這5000個檔案進行歸併(類似與歸併排序)的過程了。
還是典型的 top k 演算法,解決方案如下:
方案 1:
順序讀取10個檔案,按照hash(query)%10 的結果將query寫入到另外10個檔案(記為)中。這樣新生成的檔案每個的大小大約也1g(假設hash函式是隨機的)。找一台內存在2g左右的機器,依次對用 hash_map(query,query_count)來統計每個query出現的次數。利用快速/堆/歸併排序按照出現次數進行排序。將排序好的query和對應的query_cout輸出到檔案中。這樣得到了10個排好序的檔案(記為)。對這10個檔案進行歸併排序(內排序與外排序相結合)。
方案 2:
一般query的總量是有限的,只是重複的次數比較多而已,可能對於所有的query,一次性就可以加入到記憶體了。這樣,我們就可以採用trie樹/hash_map等直接來統計每個query出現的次數,然後按出現次數做快速/堆/歸併排序就可以了。
方案 3:
與方案 1 類似,但在做完 hash,分成多個檔案後,可以交給多個檔案來處理,採用分布式的架構來處理(比如 mapreduce),最後再進行合併。
方案 1:可以估計每個檔案安的大小為 5g×64=320g,遠遠大於記憶體限制的 4g。所以不可能將其完全載入到記憶體中處理。考慮採取分而治之的方法。
遍歷檔案a,對每個url求取hash(url)%1000,然後根據所取得的值將url分別儲存到 1000個小檔案(記為 a0,a1,…,a999)中。這樣每個小檔案的大約為300m。遍歷檔案b,採取和a相同的方式將url分別儲存到1000小檔案(記為b0,b1,…,b999)。
這樣處理後,所有可能相同的url都在對應的小檔案(a0vsb0,a1vsb1,…,a999vsb999)中,不對應的小檔案不可能有相同的url。然後我們只要求出 1000 對小檔案中相同的 url即可。
求每對小檔案中相同的url時,可以把其中乙個小檔案的url儲存到hash_set中。然後遍歷另乙個小檔案的每個url,看其是否在剛才構建的hash_set中,如果是,那麼就是共同的url,存到檔案裡面就可以了。
方案2:如果允許有一定的錯誤率,可以使用bloom filter,4g記憶體大概可以表示340億bit。將其中乙個檔案中的url使用bloom filter對映為這340億 bit,然後挨個讀取另外乙個檔案的url,檢查是否與 bloomfilter,如果是,那麼該 url 應該是共同的 url(注意會有一定的錯誤率)。
bloom filter 日後會在本 blog 內詳細闡述。
方案 1:採用2-bitmap(每個數分配 2bit,00 表示不存在,01 表示出現一次,10 表示多次,11 無意義)進行,共需記憶體 2^32 * 2 bit=1 gb 記憶體,還可以接受。然後掃瞄這2.5億個整數,檢視bitmap中相對應位,如果是00變01,01變10,10保持不變。所描完事後,檢視bitmap,把對應位是01的整數輸出即可。
方案 2:也可採用與第 1 題類似的方法,進行劃分小檔案的方法。然後在小檔案中找出不重複的整數,並排序。然後再進行歸併,注意去除重複的元素。
與上第 6 題類似,我的第一反應時快速排序+二分查詢。以下是其它更好的方法:
方案 1:oo,申請 512m 的記憶體,乙個 bit 位代表乙個 unsigned int 值。讀入 40 億個數,設定相應的 bit 位,讀入要查詢的數,檢視相應 bit 位是否為 1,為 1 表示存在,為 0 表示不存在。
dizengrong:
又因為 2^32 為 40 億多,所以給定乙個數可能在,也可能不在其中;
這裡我們把 40 億個數中的每乙個用 32 位的二進位制來表示,假設這 40 億個數開始放在乙個檔案中。
然後將這 40 億個數分成兩類: 1.最高位為0;2.最高位為1。
並將這兩類分別寫入到兩個檔案中,其中乙個檔案中數的個數<=20 億,而另乙個》=20 億(這相當於折半了);
與要查詢的數的最高位比較並接著進入相應的檔案再查詢,再然後把這個檔案為又分成兩類:
1.次最高位為 0
2.次最高位為 1
並將這兩類分別寫入到兩個檔案中,其中乙個檔案中數的個數<=10 億,而另乙個》=10 億
(這相當於折半了);
與要查詢的數的次最高位比較並接著進入相應的檔案再查詢。
以此類推,就可以找到了,而且時間複雜度為o(logn),方案 2 完。
附:這裡,再簡單介紹下,位圖方法:
使用位圖法判斷整形陣列是否存在重複判斷集合中存在重複是常見程式設計任務之一,當集合中資料量比較大時我們通常希望少進行幾次掃瞄,這時雙重迴圈法就不可取了。
位圖法比較適合於這種情況,它的做法是按照集合中最大元素 max 建立乙個長度為 max+1的新陣列,然後再次掃瞄原陣列,遇到幾就給新陣列的第幾位置上 1,如遇到 5 就給新陣列的第六個元素置 1,這樣下次再遇到 5 想置位時發現新陣列的第六個元素已經是 1 了,這說明這次的資料肯定和以前的資料存在著重複。這種給新陣列初始化時置零其後置一的做法類似於位圖的處理方法故稱位圖法。它的運算次數最壞的情況為2n。如果已知陣列的最大值即能事先給新陣列定長的話效率還能提高一倍。
方案 1:上千萬或上億的資料,現在的機器的記憶體應該能存下。所以考慮採用hash_map/搜尋二叉樹/紅黑樹等來進行統計次數。然後就是取出前n個出現次數最多的資料了,可以用第 2 題提到的堆機制完成。
方案 1:這題是考慮時間效率。用trie樹統計每個詞出現的次數,時間複雜度是 o(n*le)(le表示單詞的平準長度)。然後是找出出現最頻繁的前10個詞,可以用堆來實現,前面的題中已經講到了,時間複雜度是 o(n*lg10)。所以總的時間複雜度,是o(n*le)與 o(n*lg10)中較大的哪乙個。
附、100w個數中找出最大的100個數。
方案1:在前面的題中,我們已經提到了,用乙個含100個元素的最小堆完成。複雜度為o(100w*lg100)。
方案 2:採用快速排序的思想,每次分割之後只考慮比軸大的一部分,知道比軸大的一部分在比100多的時候,採用傳統排序演算法排序,取前100個。複雜度為o(100w*100)。
方案3:採用區域性淘汰法。選取前100個元素,並排序,記為序列l。然後一次掃瞄剩餘的元素x,與排好序的100個元素中最小的元素比,如果比這個最小的要大,那麼把這個最小的元素刪除,並把x利用插入排序的思想,插入到序列l中。依次迴圈,知道掃瞄了所有的元素。複雜度為 o(100w*100)。
hadoop案例之topK問題
海量資料中,查詢topk問題的hadoop解法 乙個map task就是乙個程序。有幾個map task就有幾個中間檔案,有幾個reduce task就有幾個最終輸出檔案。要找的top k 是指的全域性的前k條資料,那麼不管中間有幾個map,reduce最終只能有乙個reduce來彙總資料,輸出to...
8 企業案例分析 1 2 3 4
8.1進入時,透過一些技術上的領先,對這個行業當時的一些產品進行了公升級換代,以此迅速站穩腳跟。過去若干年,主要舉措 1.迅速擴大規模 自身投資和兼併收購 2.開拓國際市場 3.拓展產品線 4.拓寬原材料 建設原材料生產基地 8.2成本分析 決定投資回報的因素 效率和效益 資金密集型 規模經濟性,有...
企業SOA架構案例分析
面向服務的架構 soa 是乙個元件模型,它將應用程式的不同功能單元 稱為服務 進行拆分,並通過這些服務之間定義良好的介面和契約聯絡起來。介面是採用中立的方式進行定義的,它應該獨立於實現服務的硬體平台 作業系統和程式語言。這使得構建在各種各樣的系統中的服務可以以一種統一和通用的方式進行互動。傳統統的兩...