經典演算法題每日演練 第十一題 Bitmap演算法

2022-02-18 08:18:18 字數 3269 閱讀 9987

在所有具有效能優化的資料結構中,我想大家使用最多的就是hash表,是的,在具有定位查詢上具有o(1)的常量時間,多麼的簡潔優美,

但是在特定的場合下:

①:對10億個不重複的整數進行排序。

②:找出10億個數字中重複的數字。

當然我只有普通的伺服器,就算2g的記憶體吧,在這種場景下,我們該如何更好的挑選資料結構和演算法呢?

一:問題分析

這年頭,大牛們寫的排序演算法也就那麼幾個,首先我們算下放在記憶體中要多少g: (10億 * 32)/(1024*1024*1024*8)=3.6g,可憐

的2g記憶體直接爆掉,所以各種神馬的資料結構都玩不起來了,當然使用外排序還是可以解決問題的,由於要走io所以暫時剔除,因為我們

要玩高效能,無望後我們想想可不可以在二進位制位上做些手腳?  

比如我要對這四個byte型別的數字做排序,該怎麼做呢?我們知道byte是佔8個bit位,其實我們可以將陣列中的值作為bit位的

key,value用」0,1「來標識該key是否出現過?下面看圖:

從圖中我們精彩的看到,我們的陣列值都已經作為byte中的key了,最後我只要遍歷對應的bit位是否為1就可以了,那麼自然就成有序陣列了。

可能有人說,我增加乙個13怎麼辦?很簡單,乙個位元組可以存放8個數,那我只要兩個byte就可以解決問題了。

可以看出我將乙個線性的陣列變成了乙個bit位的二維矩陣,最終我們需要的空間僅僅是:3.6g/32=0.1g即可,要注意的是bitmap排序不

是n的,而是取決於待排序陣列中的最大值,在實際應用上關係也不大,比如我開10個執行緒去讀byte陣列,那麼複雜度為:o(max/10)。

二:**

我想bitmap的思想大家都清楚了,這一次又讓我們見證了二進位制的魅力,當然這些移位都是位運算的工作了,熟悉了你就玩轉了。

1:clear方法(將陣列的所有bit位置0)

比如要將當前4對應的bit位置0的話,只需要1左移4位取反與b[0] & 即可。

1         #region 初始化所用的bit位為0

2 /// 3 /// 初始化所用的bit位為0

4 ///

5 ///

6 static void clear(byte i)

7

20 #endregion

2:add方法(將bit置1操作)

同樣也很簡單,要將當前4對應的bit位置1的話,只需要1左移4位與b[0] | 即可。

1 #region 設定相應bit位上為1

2 /// 3 /// 設定相應bit位上為1

4 ///

5 ///

6 static void add(byte i)

7

20 #endregion

2:contain方法(判斷當前bit位是否是1)

如果看懂了clear和add,我相信最後乙個方法已經不成問題了。

1         #region 判斷當前的x在陣列的位中是否存在

2 /// 3 ///判斷當前的x在陣列的位中是否存在

4 ///

5 ///

6 ///

7 static bool contain(byte i)

8

15 #endregion

最後上總的**:

view code

1

using

system;

2using

system.collections.generic;

3using

system.linq;

4using

system.text;

5using

system.diagnostics;

6using

system.threading;

7using

system.io;89

namespace10"

, s);

3132 s = contain(5

);33

34 console.writeline("

當前是否包含5:

", s);

3536

console.read();37}

3839

#region 初始化所用的bit位為0

40///

41///

初始化所用的bit位為0

42///

43///

44static

void clear(byte

i)45

58#endregion

5960

#region 設定相應bit位上為1

61///

62///

設定相應bit位上為1

63///

64///

65static

void add(byte

i)66

79#endregion

8081

#region 判斷當前的x在陣列的位中是否存在

82///

83///

判斷當前的x在陣列的位中是否存在

經典演算法題每日演練 第十一題 Bitmap演算法

在所有具有效能優化的資料結構中,我想大家使用最多的就是hash表,是的,在具有定位查詢上具有o 1 的常量時間,多麼的簡潔優美,但是在特定的場合下 對10億個不重複的整數進行排序。找出10億個數字中重複的數字。當然我只有普通的伺服器,就算2g的記憶體吧,在這種場景下,我們該如何更好的挑選資料結構和演...

經典演算法題每日演練 第十二題 線段樹

這一篇我們來看樹狀陣列的加強版線段樹,樹狀陣列能玩的線段樹一樣可以玩,而且能玩的更好,他們在區間求和,最大,平均 等經典的rmq問題上有著對數時間的優越表現。一 線段樹 線段樹又稱 區間樹 在每個節點上儲存乙個區間,當然區間的劃分採用折半的思想,葉子節點只儲存乙個值,也叫單元節點,所 以最終的構造就...

經典演算法題每日演練 第十九題 雙端佇列

話說大學的時候老師說妹子比工作重要 工作可以再換,妹子這個。所以。這兩個月也就一直忙著fall in love,嗨,慢慢調整心態吧,這篇就選乙個簡單的資料結構聊一聊,話說有很多資料結構都在玩組合拳,比如說 塊狀鍊錶,塊狀陣列,當然還有本篇的雙端佇列,是的,它就是 棧和佇列的組合體。一 概念 我們知道...