大數據幾乎是新興行業當中繞不開的話題了,當真正接觸或從事大數據以后,應該以什么思路去把這個不容易啃的硬骨頭解決掉呢?跟隨大圣眾包威客平臺(www.dashengzb.cn)的腳步一探究竟吧!
一、解決大數據問題的主要思路
不同的人,對大數據也有著不同的理解,從實際意義上看,大數據可以指種類多、流量大、容量大、價值高、處理和分析速度快的真實數據匯聚的產物。通常應用于存儲空間、提高效率等問題上。而解決大數據問題的一般主要思想有如下:
1.文件切分(將大文件切成若干個小文件進行處理);
2.哈希切分;
3.使用位圖。
二、結合實例,處理大數據問題
1.在海量的日志數據中,提取出某日訪問百度次數最多的那個IP;或在一個超過100G的IP地址文件中找出出現次數最多的IP地址。
【分析】:
這兩個題是同類型的題。IP的數目還是有限的,最多有個2^32(42億)個IP,而且應注意到IP是32位的。
1byte=8位
1KB=1024bytes(字節)
1MB=1024KB
1GB=1024MB
假設每個IP只出現一次,所需內存大概為(32*2^32)位,約為16個G左右。如果內存足夠大,就直接進行統計;但是如果內存沒有那么大,可以將大文件切分成若干個小文件(假設為100個小文件),再采用映射的方法。比如用IP地址模1000,這樣,同一個IP地址肯定會出現在同一個小文件中,再找出每個小文中出現頻率最大的IP(可以采用hash_map進行頻率統計,然后再找出頻率最大的幾個)及相應的頻率,然后再在這1000個最大的IP中,找出那個頻率最大的IP,即為所求。
2.給定100億個整數,設計算法找到只出現一次的整數。
【分析】:
如果是有符號整數的話,范圍為-2147483648~2147483647,無符號整數的話,范圍為0~4294967296。有符號的,使用兩個bitset,一個存放正數,一個存放負數。每個數使用兩個位來判斷其出現幾次。00表示出現0次,01出現1次,10出現大于一次。
比如說存放整數100,就將bitset的第100*2位設置為+1,當所有數放完之后,對每兩位進行測試,看其值為多少。若是第i與i+1的值為01,則這個整數:i*2,在集合中只出現了1次,需要總共用bitnum=(2^31*2)個位表示,需空間為int[bitnum],即512M。
3.當前有40億個不重復的、沒排過序的unsignedint的整數,也有一個任意數,如何快速判斷這個任意數是否在那40億個數當中。
【分析1】:
40億個整數差不多相當于全部整數,需要總共用(2^32)個位表示,需空間為int[bitnum],即512M。申請512M的內存,一個bit位代表一個unsignedint值。再讀入40億個數,設置相應的bit位,讀入要查詢的數,查看相應bit位是否為1。為1表示存在,為0表示不存在。
【分析2】:
因為2^32為40億多,所以這個任意數可能在,也可能不在其中。
可以先把40億個數中的每一個用32位的二進制來表示,假設這40億個數是放在一個文件中的,再將這40億個數分成兩類:分別是最高位為0和最高位為1,并將這兩類分別寫入到兩個文件中,其中一個文件中數的個數≤20億,而另一個≥20億(這相當于折了),再與要查找的數的最高位比較并進入相應的文件再查找。然后把這個文件為又分成兩類:分別是次最高位為0和次最高位為1,并將這兩類分別寫入到兩個文件中,其中一個文件中數的個數≤10億,而另一個≥10億(這相當于折半了),再與要查找的數的次最高位比較并接著進入相應的文件再查找……如此類推,便能找到結果,而且時間復雜度僅為O(logn)。
【分析3】:
此例還可以使用位圖方法。位圖法是常見編程任務之一,它能夠判斷整形數組是否存在重復判斷集合中存在重復。當集合中數據量比較大時,通常希望少進行幾次掃描,這時雙重循環法就不可取了。但是,位圖法就比較適合這種情況。
它的做法是,按照集合中最大元素max創建一個長度為max+1的新數組,然后再次掃描原數組,遇到幾就給新數組的第幾位置上1,如遇到5就給新數組的第六個元素置1,這樣下次再遇到5想置位時發現新數組的第六個元素已經是1了,這說明這次的數據肯定和以前的數據存在著重復。它的運算次數最壞的情況為2N。如果已知數組的最大值,即能事先給新數組定長的話效率還能提高一倍。