模擬雜湊表
引入雜湊表就是根據乙個關鍵值key進行高效訪問的資料結構,可以通過雜湊函式把乙個資料當做key進行對映得到乙個儲存位址從而進行訪問。
比如想要查詢100個數字範圍在(1 ~ 1e8),查詢它們是否有重複的值,那麼就可以用雜湊表來解決這個問題。
對於小的數字我們就會習慣的會去乙個陣列進行標記,但是對於大的數字,開乙個很大陣列用來標記是很浪費空間,而且要處理的數只有100個,開乙個1e8的陣列實在是划不來,而且當資料再增大時,對於c++可能就無法直接開出這樣的陣列。
雜湊函式
此時就可以對此些數字進行轉換,比如,我們可以對其進行取模,這樣就可以把他們都轉化成一定範圍的數字。
這種把這些資料按照一定方式進行轉化的函式就稱之為雜湊函式,上面所使用的雜湊函式就是取模。
處理衝突
可以發現用雜湊函式處理之後,可能存在相同的值,比如5 % 3 = 2, 8 % 3 = 2這樣就可能會使查詢的結果錯誤,那麼就需要用一種方式處理衝突了(可以證明當模數取質數時衝突機率最小)。
拉鍊法拉鍊法處理衝突很簡單,對於幾個重複的值可以把他們放在乙個煉表裡,查詢時只需要去翻查鍊錶就可以知道是否存在了
using
namespace std;
const
int mod =
100003
;int h[
100005
],cnt =
1,n;
struct nodeedge[
100005];
//鍊錶
void
insert
(int x)
bool
find
(int x)
return
false
;}
字串雜湊
字串的雜湊可以採用字首雜湊(在競賽中)
對於乙個字串可以把它當成乙個p進製的數字,比如用sum來表示字首對於字串:「acf」
那麼就有:
s um
[1]=
p∗『a
』sum[1] = p * 『a』
sum[1]
=p∗『
a』s um
[2]=
p2∗『
c』+s
um[1
]sum[2] = p^2 * 『c』 + sum[1]
sum[2]
=p2∗
『c』+
sum[
1]s um
[3]=
p3∗『
f』+s
um[2
]sum[3] = p^3 * 『f』 + sum[2]
sum[3]
=p3∗
『f』+
sum[
2]但是這樣就會有乙個問題,最後求出來的數字很大,所以就需要進行取模。然後就可以完成字首hash了。
對於p一般取131,對於模數一般取2
642^
264這樣開unsigned long long進製時就會自動取模了,對於重複的字串,重複的機率很小,所以幾乎可以當做不重複,如果相求某一段字串的雜湊值那麼就可以用sum
[r]−
sum[
l−1]
∗pr−
l+
1sum[r] - sum[l - 1] * p^
sum[r]
−sum
[l−1
]∗pr
−l+1
這個公式求得
題目:字串hash
#include
#define inf 0x3f3f3f3f
#define ll long long
#define eps 1e-8
using
namespace std;
const ll maxn =
1e5+5;
typedef
unsigned
long
long ull;
int n,m,l1,r1,l2,r2;
ull p[maxn]
,sum[maxn]
;char str[
100005];
ull finds
(int l,
int r)
intmain()
while
(m--
)return0;
}
資料結構 雜湊表(模擬雜湊表 字串雜湊)
1.雜湊表的定義 給定表m,存在函式f key 對任意給定的關鍵字值key,代入函式後若能得到包含該關鍵字的記錄在表中的位址,則稱表m為雜湊 hash 表,函式f key 為雜湊 hash 函式。2.雜湊表的用途 把乙個較大範圍的值域對映到乙個較小的範圍 3.雜湊表的原理 通過對大數取餘運算把乙個大...
雜湊 字串雜湊演算法
給定乙個長度為n的字串,再給定m個詢問,每個詢問包含四個整數l1,r1,l2,r2,請你判斷 l1,r1 和 l2,r2 這兩個區間所包含的字串子串是否完全相同。字串中只包含大小寫英文本母和數字。輸入格式 第一行包含整數n和m,表示字串長度和詢問次數。第二行包含乙個長度為n的字串,字串中只包含大小寫...
字串雜湊
參照演算法筆記p109,甲級1039 先假設字串均由大寫字母a z構成。在這個基礎上,不妨把a z視為0 25,這樣就把26個大寫字母對應到了26進製中。接著,按照將26進製轉化為10進製的思路,由進製的轉換結論可知,在進製轉換過程中,得到的10進製肯定是唯一的,由此便可實現將字串對映為整數的需求 ...