雜湊表實戰經驗

2021-10-05 14:53:57 字數 2579 閱讀 8922

雜湊表的作用:簡單來說就是將乙個龐大的值域(複雜的資料結構)對映到乙個較小的空間(例如0 ~ n,n 為1e5或1e6等比較小的數)

通常寫雜湊函式最簡單方法就是:例如:h(x) = x mod 10^5,將很大的x對映到10^5內。但是往往會面臨衝突,因為值域太大,經過雜湊函式的計算對映的值相同。那麼如何處理衝突呢?線性探測、二次探測、開鏈

這裡介紹雜湊表的兩種儲存結構:(1)開放定址法(這裡採用線性探測)(2)拉鍊法

概念:(1)負載係數:待插入元素的個數 / 一維陣列的大小

1、拉鍊法  負載係數大於1

如圖所示:開(例:10^5)個槽(乙個一維陣列),將相同對映值接在每乙個槽的下面,相當於一條拉鍊,單鏈表

雜湊表為一種期望演算法,在平均情況下,每一條鏈的長度都可以看作常數,因此時間複雜度通常是很小的o(1),新增,查詢,刪除的話就開乙個bool變數進行標記(惰性刪除)。

**例程:實現插入和查詢兩種操作

#include #include using namespace std;

const int n = 100003; // 取大於100000的最近的質數,離2的整次冪盡量遠,衝突的概率最小

int h[n]; //槽

int e[n], ne[n]; //單鏈表

int idx; //當前運算元

void insert(int x)

bool find(int x)

int main()

}return 0;

}

sgi stl中的hash table採用的是拉鍊法,

2、開放定址法

沒有開拉鍊,形式上簡單些,經驗上他開的一維陣列要開到兩到三倍,這樣衝突就會比較低了,處理衝突的方式,類似於上廁所,這個位置有人,則去下乙個。

**例程:實現插入和查詢

#include #include using namespace std;

const int n = 200003; //經驗值將陣列開兩到三倍大小,此處開兩倍,最接近的質數

const int null = 0x3f3f3f3f; //設定大於1e9的數字,只要不在我們的值域範圍內就可以

int h[n];

int find(int x)

return t; //若找到,返回的就是x在的位置,若沒找到,返回的就是x應該存放的位置

}int main()

}return 0;

}

此處採用的是線性探測,也可以採用二次探測,即使用雜湊函式得到元素在陣列中的位置為h,但是這個位置被使用了,那麼可以依次嘗試h + 1^2, h + 2^2, h + 3^2, …, h + i^2。在這裡,我們只要保證陣列的大小為質數,並且負載係數在0.5以下(超過0.5需要重新配置並重新整理**),那麼就可以確定每插入乙個元素所需要的探測次數不多於2。

3、字串的雜湊,預處理字首的雜湊

**例程:實現判斷乙個長串中任意兩個字串是否相同

#include #include using namespace std;

typedef unsigned long long ull; //溢位ull相當於對2^64取模

const int n = 100010, p = 131; //經驗值,或者取13331

int n, m;

char str[n];

ull h[n], p[n];

ull get(int l, int r) //獲得l,r之間的雜湊值

int main()

while(m --)

return 0;

}

4、stl中的set和map

set/multiset

insert() 插入乙個數

find() 查詢乙個數

count() 返回某乙個數的個數

erase()

(1) 輸入是乙個數x,刪除所有x o(k + logn)

(2) 輸入乙個迭代器,刪除這個迭代器

lower_bound()/upper_bound()

lower_bound(x) 返回大於等於x的最小的數的迭代器

upper_bound(x) 返回大於x的最小的數的迭代器

map/multimap

insert() 插入的數是乙個pair

erase() 輸入的引數是pair或者迭代器

find()

注意multimap不支援此操作。 時間複雜度是 o(logn)

lower_bound()/upper_bound()

unordered_set, unordered_map, unordered_multiset, unordered_multimap, 雜湊表

和上面類似,增刪改查的時間複雜度是 o(1)

不支援 lower_bound()/upper_bound(), 迭代器的++,--

MongoDB實戰經驗分享

nosql並不是no sql,而是指not only sql。nosql的出現是為了彌補sql資料庫因為事務等機制帶來的對海量資料 高併發請求的處理的效能上的欠缺。nosql不是為了替代sql而出現的,它是一種替補方案,而不是解決方案的首選。絕大多數的nosql產品都是基於大記憶體和高效能隨機讀寫的...

Spark專案實戰經驗

auto.offset.reset 啟動時讀取的偏移量。如果是需要歷史資料那麼設定成earliest 如果不需要消費歷史資料那麼設定成latest 1 如果自動提交偏移量 spark streaming消費到資料之後立馬提交,那麼就會有乙個問題 提交偏移量成功 處理失敗了,那麼spark strea...

linux 實戰經驗(4)

linux系統密碼破解 redhat6 以6以下版本 1 重新啟動,在系統重啟後的開始介面快速按空格鍵,進入如下介面 2 按 e 進入以下介面 3 選擇第二行,按e編輯 在末尾加乙個空格 後面輸入個 1或者single 如上圖 按esc退回到上一步,按b重啟,進入單使用者模式 可以繞過初始密碼 4 ...