C++雜湊應用-點陣圖/布隆過濾器/海量資料處理

vjvj1101發表於2022-04-16

C++點陣圖/布隆過濾器/海量資料處理

零、前言

一、點陣圖

1、點陣圖概念

2、點陣圖介面的介紹以及實現

3、點陣圖的應用

二、布隆過濾器

1、布隆過濾器概念和介紹

2、布隆過濾器的操作及實現

3、布隆過濾器的分析

三、海量資料處理

零、前言

本章主要講解C++中對雜湊的應用有關方面的內容,點陣圖,布隆,海量資料處理


一、點陣圖

1、點陣圖概念

點陣圖概念:

點陣圖其實就是雜湊的變形,同樣通過對映來處理資料,只不過點陣圖本身並不儲存資料,而是儲存標記


通過一個位元位來標記這個資料是否存在,1代表存在,0代表不存在


點陣圖通常情況下用在資料量龐大,且資料不重複的情景下判斷某個資料是否存在


相關面試題描述:

給40億個不重複的無符號整數,沒排過序。給一個無符號整數,如何快速判斷一個數是否在這40億個數中


注意:

遍歷時間複雜度O(N);排序(O(NlogN))利用二分查詢: logN;這兩種方式除了效率不夠高,還有個問題是記憶體無法完全同時載入這給40億個不重複的無符號整數


10億個整數為40億位元組,而10億位元組為1G,所以40億個整數需要16G大小空間


點陣圖解決方案:

資料是否在給定的整形資料中,結果是在或者不在,剛好是兩種狀態


那麼可以使用一個二進位制位元位來代表資料是否存在的資訊,如果二進位制位元位為1,代表存在,為0代表不存在


示圖:小端平臺上


2、點陣圖介面的介紹以及實現

bitset中常用的成員函式如下:

成員函式 功能

set 設定指定位或所有位

reset 清空指定位或所有位

flip 反轉指定位或所有位

test 獲取指定位的狀態

count 獲取被設定位的個數

size 獲取可以容納的位的個數

any 如果有任何一個位被設定則返回true

none 如果沒有位被設定則返回true

all 如果所有位都被設定則返回true

使用示例:

#include <iostream>

#include <bitset>

using namespace std;


int main()

{

bitset<8> bs;

bs.set(2); //設定第2位

bs.set(4); //設定第4位

cout << bs << endl; //00010100

bs.flip(); //反轉所有位

cout << bs << endl; //11101011

cout << bs.count() << endl; //6

cout << bs.test(3) << endl; //1

bs.reset(0); //清空第0位

cout << bs << endl; //11101010

bs.flip(7); //反轉第7位

cout << bs << endl; //01101010

bs.reset(); //清空所有位

cout << bs.none() << endl; //1

bs.set(); //設定所有位

cout << bs.all() << endl; //1

return 0;

}


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

注:使用成員函式set、reset、flip時,若指定了某一位則操作該位,若未指定位則操作所有位


點陣圖的簡單實現:

對於底層來說一個位代表一個數的對映,那麼我們以char型別來開闢對應需要空間,同時用vector進行管理


對於開闢空間,一個char型別有8個位,所以需要個數/8即為需要開闢的大小,但是整數相除為向下取整,所以需要我們多開一個空間出來


實現程式碼:

template<size_t N>

class bitset

{

public:

bitset()

{

_bits.resize(N / 8 + 1,0);//開闢空間並置為0

//_bits.resize((N >> 3) + 1,0);

}

bool test(size_t x)

{

size_t i = x / 8;//處於的該陣列的第幾個空間

size_t j = x % 8;//處於的該空間的第幾個位元位


return _bits[i] & (1 << j);

}


void set(size_t x)

{

size_t i = x / 8;//處於的該陣列的第幾個空間

size_t j = x % 8;//處於的該空間的第幾個位元位


_bits[i] |= (1 << j);//該位置置為1

}


void reset(size_t x)

{

size_t i = x / 8;//處於的該陣列的第幾個空間

size_t j = x % 8;//處於的該空間的第幾個位元位


_bits[i] &= (~(1 << j));//該位置置為0

}

private:

vector<char> _bits;

};


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

3、點陣圖的應用

快速查詢某個資料是否在一個集合中


排序


求兩個集合的交集、並集等


作業系統中磁碟塊標記


二、布隆過濾器

1、布隆過濾器概念和介紹

布隆過濾器的提出:

我們在使用新聞客戶端看新聞時,它會給我們不停地推薦新的內容,它每次推薦時要去重,去掉那些已經看過的內容。問題來了,新聞客戶端推薦系統如何實現推送去重的?


用伺服器記錄了使用者看過的所有歷史記錄,當推薦系統推薦新聞時會從每個使用者的歷史記錄裡進行篩選,過濾掉那些已經存在的記錄


如何快速查詢:

用雜湊表儲存使用者記錄,缺點:浪費空間


用點陣圖儲存使用者記錄,缺點:不能處理雜湊衝突


將雜湊與點陣圖結合,即布隆過濾器


布隆過濾器概念:

布隆過濾器是由布隆(Burton Howard Bloom)在1970年提出的 一種緊湊型的、比較巧妙的概率型資料結構


特點是高效地插入和查詢,可以用來告訴你 “某樣東西一定不存在或者可能存在”


它是用多個雜湊函式,將一個資料對映到點陣圖結構中的不同位置上,不僅可以提升查詢效率,也可以節省大量的記憶體空間




來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70016760/viewspace-2887455/,如需轉載,請註明出處,否則將追究法律責任。

相關文章