大數運算分析

2021-10-24 08:59:23 字數 3315 閱讀 2371

何為大數運算?

就是資料量過多, 記憶體放不下, 如何去處理的問題? 下面我們通過例題分析

在這裡, 我們先講一些換算公式:

1g = 10億byte, 2g = 20億byte

一般記憶體大小為4g, 核心占用2g, 使用者最大能夠使用2g左右(我們一般認為使用者最多能夠使用2g空間)

一、給乙個超過100g大小的ip位址, 設計演算法找到出現次數最多的ip位址?

100g的ip位址, ip為4byte, 如果想要全部存在, 需要100*4 = 400g大小的空間

而我們只有2g空間的大小, 很顯然是存不下的。

分析:

我們可以將100g的ip位址 劃分為 1000(具體應該為1024) 份 100m大小的小檔案。100m大小我們記憶體是存得下的, 那麼大體的處理流程就是每次讀取100m的小檔案處理, 最終把1000份小檔案都處理完畢。

那麼該如何處理呢?

我們採用雜湊切割, 也就是通過雜湊函式將ip分類(ip位址 % 1000 = 第幾個小檔案), 這樣做得目的是為了保證所有相同的ip位址都放到乙個小檔案中。

處理邏輯:

1、將100g個ip位址劃分為1000份 100m大小的小檔案。

2、對所有100g個ip位址 進行 雜湊切割, 進行分類, 保證相同的ip位址放到同乙份小檔案中。

3、每次讀取乙個小檔案500m放到記憶體中處理, 採用乙個max變數記錄最大值ip值(也就是在這個檔案重複次數最多的)。對這個500m的檔案所有重複的ip進行處理, 獲取這個max值, 然後讀取下乙個小檔案, 如果下乙個小檔案中最大重複ip值大於上乙個max值, 就更新max值。 最後處理完所有的小檔案。

4、最終這個max值儲存的就是重複次數最多的ip值,即我們所需要的。

二、給乙個超過100g大小的ip位址, 設計演算法找到出現前k的ip位址?

這道題和第一道同樣的處理方式

第一步: 分小檔案

第二部: 雜湊切割

第三步: 處理

不同的在於處理方式不同, 這道題需要用到topk的設計思路。(不懂這個思想的朋友可以先了解下)

處理邏輯:

我重點講第三步處理, 前兩步的處理和第一步相同,不多做敘述。

我們採用堆去來做這道題。

構建乙個小根堆, 大小(容量)為k,每次讀取乙個小檔案100m放到記憶體處理, 然後對小檔案中的所有ip乙個乙個處理。

1、首先在前面剛開始的時候, 我們先保證把小根堆存滿。當存滿之後, 後續的ip我們處理。

2、對於乙個ip位址, 我們首先判斷在小根堆中是否存在, 如果存在, 就不管了, 換下乙個ip, 如果不存在, 則判斷這個ip值是否大於堆頂元素, 如果大於, 則pop堆頂元素, 然後把這個ip入堆。 以此類推!

3、最終處理完所有小檔案之後, 這個小根堆中儲存的就是出現次數最多的前k個ip位址, 即我們需要的答案。

三、從100億的整形資料中找到只出現一次的整數

100億個整形資料, 運算下來100*4 = 400億byte大小, 大約為40g開銷,

很顯然, 是存不下的。

1、你可以採用上述的分割小檔案, 雜湊切割處理。

2、整數的範圍為2^32 = 42億多種情況, 根據1g=1億byte, 換算下來42億需要4g空間, 然後這是不包含重複的, 考慮只出現一次的情況。

如果採用int型別儲存需要空間為4g*4=16g的開銷

採用點陣圖呢? 由於存在重複多次的情況, 採用一位儲存是不行的, 我們需要2位儲存乙個元素

那麼in型別32位儲存 --> 需要16g開銷, 2位儲存,空間效能提公升16倍, 即需要16g/16 = 1g的開銷就可以存得下, 很顯然記憶體是存得下的,棒棒的!

那麼這塊我就講乙個採用位圖實現的邏輯:

2位儲存乙個資料, 00-代表元素個數為0; 01-代表這個元素個位為1; 10-代表這個元素》1

實現邏輯:

1、開闢1g空間的點陣圖,表示儲存2^32=42億所有整數的情況。

2、然後把100億整數資料 - 40g大小資料 劃分為 很多個小檔案, 每次讀取乙個小檔案放到記憶體處理, 當讀取到乙個整數時, 首先判斷這個元素對應位圖情況:

如果為00, 代表第一次出現, 則置為01,

如果為01, 代表第二次出現, 則置為10,

如果為10, 代表多次出現, 不需要處理。

最終把所有的小檔案處理完(也就是把100億個整數處理完), 然後對這個位圖進行判斷, 從-24億到24億多(也就是所有整數的情況)判斷, 看對應的點陣圖是否為10, 如果為10,則代表這個數出現過一次。 即也是我們想要找到的答案。

四、 給兩個檔案,分別有100億個整數,我們只有1g記憶體,如何找到兩個檔案交集?

這道題如果你明白第三道的思路, 這道題你可以玩出花來。

同樣,是基於第三道的思想, 我採用點陣圖去做,剛才第三道題因為需要2位儲存乙個數, 最終算出來需要1g空間的開銷, 如今我們不需要考慮重複的情況, 因為只要在這兩個100億的數,不管兩個對於乙個整數重複多少次, 只要雙方有一次,就可以判斷這個數就是交集之一。

因此我不需要2位儲存乙個數, 一次儲存就可以, 相對於第三題的空間提公升, 我們這裡還可以提公升2倍, 也就是不要1g, 1g/2 = 500m(實際上是512m)的開銷就可以。

那麼我們建立兩個500m的點陣圖, 加起來也就是1g左右, 我們儲存是存得下的。

處理邏輯:

1、基於第三道的思想,建立兩個500m的點陣圖, 然後處理對應的100億的資料。

2、我講乙個100億的處理,另100億處理同理。採用第三題的思想, 將100億的資料劃分位小檔案,每次讀取乙個小檔案到記憶體進行處理。

當乙個元素對應的位為0時, 代表第一次來, 將它置為1。

如果為1時,代表》1次來, 我不需要處理。 (因為我只是想表示這個數存在就ok啦)

3、然後將兩個500m的點陣圖,分別對比, 從所有整形的情況判斷(-24億多~24億多), 如果點陣圖1存在, 點陣圖2也存在, 就是交集之一。 以此類推!

大數運算之大數相減

大數減法運算 第一次在csdn寫部落格,督促自己不斷學習 鞏固和進步,希望能和大家一起成長 在程式設計實現整數運算時,作為程式猿 媛,我們知道計算機中的int long或者long long的所佔的記憶體空間是有限的,當整數超過一定大小,這些型別就無法表示整數的值,否則資料會被 截斷 無法得到正確的...

大數運算 冪次方運算

以下演算法計算n的m次方 m的定義域是 1,2 31 n的定義域是 0,65535 原理就是按位相乘,處理進製 include include include void main void std vectorvecnum 1,n 用vector儲存大數,首位賦n for int i 0 i m 1...

超長整數運算(大數運算)

說明基於記憶體的有效運用,程式語言中規定了各種不同的資料型態,也因此變數所可以表達的最大整數受到限制,例如123456789123456789這樣的整數就不可能儲存在long變數中 例如c c 等 我們稱這為long數,或俗稱大數運算。解法乙個變數無法表示超長整數,則就使用多個變數,當然這使用陣列最...