如何從大量數據中找出高頻詞


題目描述

  有一個 1GB 大小的文件,文件里每一行是一個詞,每個詞的大小不超過 16B,內存大小限制是 1MB,要求返回頻數最高的 100 個詞(Top 100)。

解答思路

  由於內存限制,我們依然無法直接將大文件的所有詞一次讀到內存中。因此,同樣可以采用分治策略,把一個大文件分解成多個小文件,保證每個文件的大小小於 1MB,進而直接將單個小文件讀取到內存中進行處理。

思路如下:

  首先遍歷大文件,對遍歷到的每個詞x,執行 hash(x) % 5000,將結果為 i 的詞存放到文件 ai 中。遍歷結束后,我們可以得到 5000 個小文件。每個小文件的大小為 200KB 左右。如果有的小文件大小仍然超過 1MB,則采用同樣的方式繼續進行分解。

  接着統計每個小文件中出現頻數最高的 100 個詞。最簡單的方式是使用 HashMap 來實現。其中 key 為詞,value 為該詞出現的頻率。具體方法是:對於遍歷到的詞 x,如果在 map 中不存在,則執行 map.put(x, 1);若存在,則執行 map.put(x, map.get(x)+1),將該詞頻數加 1。

  上面我們統計了每個小文件單詞出現的頻數。接下來,我們可以通過維護一個小頂堆來找出所有詞中出現頻數最高的 100 個。具體方法是:依次遍歷每個小文件,構建一個小頂堆,堆大小為 100。如果遍歷到的詞的出現次數大於堆頂詞的出現次數,則用新詞替換堆頂的詞,然后重新調整為小頂堆,遍歷結束后,小頂堆上的詞就是出現頻數最高的 100 個詞。

方法總結

  1. 分而治之,進行哈希取余,文件分割;
  2. 使用 HashMap 統計頻數;
  3. 求解最大的 TopN 個,用小頂堆;求解最小的 TopN 個,用大頂堆。

 

題型變化——》

題目描述

現有海量日志數據保存在一個超大文件中,該文件無法直接讀入內存,要求從中提取某天訪問百度次數最多的那個 IP

解答思路

這道題只關心某一天訪問百度最多的 IP,因此,可以首先對文件進行一次遍歷,把這一天訪問百度 IP 的相關信息記錄到一個單獨的大文件中。接下來采用的方法與上一題一樣,大致就是先對 IP 進行哈希映射,接着使用 HashMap 統計重復 IP 的次數,最后計算出重復次數最多的 IP。

注:這里只需要找出出現次數最多的 IP,可以不必使用堆,直接用一個變量 max 即可。

方法總結

  1. 分而治之,進行哈希取余;
  2. 使用 HashMap 統計頻數;
  3. 求解最大的 TopN 個,用小頂堆;求解最小的 TopN 個,用大頂堆。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM