資料結構 雜湊表(模擬雜湊表 字串雜湊)

2021-10-23 14:08:31 字數 4288 閱讀 8059

1. 雜湊表的定義

給定表m,存在函式f(key),對任意給定的關鍵字值key,代入函式後若能得到包含該關鍵字的記錄在表中的位址,則稱表m為雜湊(hash)表,函式f(key)為雜湊(hash) 函式。

2. 雜湊表的用途

把乙個較大範圍的值域對映到乙個較小的範圍

3. 雜湊表的原理

通過對大數取餘運算把乙個大數對映到乙個較小的範圍,若取餘結果有衝突則進行處理

4. 兩種儲存結構

根據對出現衝突時的不同處理方式,把雜湊表分為兩類:開放定址法、拉鍊法

5. 兩種模板

(

1) 拉鍊法

int h[n]

, e[n]

, ne[n]

, idx;

// 向雜湊表中插入乙個數

void

insert

(int x)

// 在雜湊表中查詢某個數是否存在

bool

find

(int x)(2

) 開放定址法

int h[n]

;// 如果x在雜湊表中,返回x的下標;如果x不在雜湊表中,返回x應該插入的位置

intfind

(int x)

return t;

}

6. 例題:模擬雜湊表

維護乙個集合,支援如下幾種操作:

1、「i x」,插入乙個數x;

2、「q x」,詢問數x是否在集合**現過;

現在要進行n次操作,對於每個詢問操作輸出對應的結果。

輸入格式

第一行包含整數n,表示運算元量。

接下來n行,每行包含乙個操作指令,操作指令為」i x」,」q x」中的一種。

輸出格式

對於每個詢問指令「q x」,輸出乙個詢問結果,如果x在集合**現過,則輸出「yes」,否則輸出「no」。

每個結果佔一行。

資料範圍

1≤n≤105

−109≤x≤109

輸入樣例:

5i 1

i 2i 3

q 2q 5

輸出樣例:

yesno

開放定址法題解

原理:把陣列開成原本資料範圍的2

~3倍,如果有衝突就把衝突的數一次向後排

#include

#include

using

namespace std;

//n為實際資料範圍10^5的兩倍,同樣取質數

//null為在資料範圍之外的乙個大數,用於標記某個陣列元素中是否為空

const

int n =

200003

, null =

0x3f3f3f3f

;int h[n]

;//儲存原資料

// 函式功能:查詢某個資料在雜湊錶即(h[n])中應該存放的下標

intfind

(int x)

return k;

}int

main()

}return0;

}

拉鍊法題解

原理:在每個陣列元素處拉一條單鏈表,儲存不同的值

#include

#include

using

namespace std;

const

int n =

100003

;//此處設為大於對映範圍最小的質數,為了減少衝突

//h[n]儲存所有煉表頭, 下標為原資料對映後的值

//e[n]儲存鍊錶資料, 即原資料

//ne[n]儲存鍊錶指標

//idx記錄當前鍊錶中節點的個數

int h[n]

, e[n]

, ne[n]

, idx;

//函式功能:在雜湊表中插入乙個數

void

insert

(int x)

// 函式功能:查詢乙個數是否在雜湊表中

bool

find

(int x)

intmain()

}return0;

}

7. 字串雜湊

(1)原理:把乙個字串看成乙個p進製數,然後把它轉化為10進製,再對他取餘進行對映

(2)雜湊步驟:

1.把乙個字串看成是131或13331進製的數(這樣衝突概率小)

2.把這個p進製數轉化為對應的10進製數

3.把轉化後的10進製數對264取餘,進行對映

(3)注意:不能把字母對映成0,因為如果是0那麼a和aa都會是0;假定我們對映後的數不會發生衝突。

(4)**步驟:

預處理p[n]、h[n],p[i]儲存pi,h[i]儲存字串前i個數的十進位制數

字串字首:h[i] = h[i-1] * p + str[i], 任意子串 = h[r] - h[l - 1] * pr-l+1

詢問區間,比較兩個區間對應的字串的十進位制數是否相等

8. 模板

核心思想:將字串看成p進製數,p的經驗值是131或13331,取這兩個值的衝突概率低

小技巧:取模的數用2

^64,這樣直接用unsigned

long

long儲存,溢位的結果就是取模的結果

typedef

unsigned

long

long ull;

ull h[n]

, p[n]

;// h[k]儲存字串前k個字母的雜湊值, p[k]儲存 p^k mod 2^64

// 初始化p[0

]=1;

for(

int i =

1; i <= n; i ++

)// 計算子串 str[l ~ r] 的雜湊值

ull get

(int l,

int r)

9.例題:字串雜湊

給定乙個長度為n的字串,再給定m個詢問,每個詢問包含四個整數 l1,r1,l2,r2 ,請你判斷[ l1,r1 ]和[ l2,r2 ]這兩個區間所包含的字串子串是否完全相同。

字串中只包含大小寫英文本母和數字。

輸入格式

第一行包含整數n和m,表示字串長度和詢問次數。

第二行包含乙個長度為n的字串,字串中只包含大小寫英文本母和數字。

接下來m行,每行包含四個整數 l1,r1,l2,r2 ,表示一次詢問所涉及的兩個區間。

注意,字串的位置從1開始編號。

輸出格式

對於每個詢問輸出乙個結果,如果兩個字串子串完全相同則輸出「yes」,否則輸出「no」。

每個結果佔一行。

資料範圍

1≤n,m≤105

輸入樣例:

8 3aabbaabb

1 3 5 7

1 3 6 8

1 2 1 2

輸出樣例:

yesno

yes

#include

using

namespace std;

typedef

unsigned

long

long ull;

const

int n =

100010

, p =

131;

int n, m;

char str[n]

;ull h[n]

, p[n]

;//用unsign long long 儲存,如果結果溢位則相當於對2^64取餘

//函式功能:計算任意子串的十進位制值

ull get

(int l,

int r)

intmain()

while

(m--

)return0;

}

模擬雜湊表 字串雜湊

模擬雜湊表 引入雜湊表就是根據乙個關鍵值key進行高效訪問的資料結構,可以通過雜湊函式把乙個資料當做key進行對映得到乙個儲存位址從而進行訪問。比如想要查詢100個數字範圍在 1 1e8 查詢它們是否有重複的值,那麼就可以用雜湊表來解決這個問題。對於小的數字我們就會習慣的會去乙個陣列進行標記,但是對...

資料結構 雜湊表(模擬雜湊表和字串雜湊)

維護乙個集合,支援如下幾種操作 i x 插入乙個數x q x 詢問數x是否在集合 現過 現在要進行n次操作,對於每個詢問操作輸出對應的結果。輸入格式 第一行包含整數n,表示運算元量。接下來n行,每行包含乙個操作指令,操作指令為 i x q x 中的一種。輸出格式 對於每個詢問指令 q x 輸出乙個詢...

資料結構 雜湊表(雜湊表)hash table

hash table 在計算機中,雜湊表 是 一種實現了關聯陣列 抽象資料型別的資料結構,這種資料結構可以對映 鍵 key 和 值 value 補充 關聯陣列 在電腦科學中,乙個關聯陣列 associative array 對映 map 符號表 symbol table 或者是字典 dictiona...