如何搭建一個(gè)簡(jiǎn)單的網(wǎng)站seo推廣排名平臺(tái)有哪些
知識(shí)概覽(哈希表)
- 哈希表可以將一些值域較大的數(shù)映射到較小的空間內(nèi),通常用x mod 質(zhì)數(shù)的方式進(jìn)行映射。為什么用質(zhì)數(shù)呢?這樣的質(zhì)數(shù)還要離2的整數(shù)冪盡量遠(yuǎn)。這可以從數(shù)學(xué)上證明,這樣沖突最小。
- 取余還是會(huì)出現(xiàn)沖突情況。怎么解決沖突呢,有兩種方式:開(kāi)放尋址法和拉鏈法。
- 算法題中哈希表的題目可能會(huì)有添加、查找操作,刪除操作較少,刪除用邏輯刪除,即用一個(gè)bool數(shù)組來(lái)標(biāo)識(shí)出哪些數(shù)已經(jīng)被刪除了。
例題展示
題目鏈接
https://www.acwing.com/problem/content/842/
代碼(拉鏈法)
#include <iostream>
#include <cstring>using namespace std;const int N = 100010;int h[N], e[N], ne[N], idx;void insert(int x)
{int k = (x % N + N) % N;e[idx] = x;ne[idx] = h[k];h[k] = idx++;
}bool query(int x)
{int k = (x % N + N) % N;for (int i = h[k]; i != -1; i = ne[i])if (e[i] == x)return true;return false;
}int main()
{int n;scanf("%d", &n);memset(h, -1, sizeof h);while (n--){char op[2];int x;scanf("%s%d", op, &x);if (*op == 'I') insert(x);else{if (query(x)) puts("Yes");else puts("No");}}return 0;
}
代碼(開(kāi)放尋址法)
#include <iostream>
#include <cstring>using namespace std;const int N = 200003, null = 0x3f3f3f3f; // 數(shù)組長(zhǎng)度設(shè)置為題目數(shù)據(jù)范圍的2~3倍且是質(zhì)數(shù)int h[N];int find(int x)
{int k = (x % N + N) % N;while (h[k] != null && h[k] != x){k++;if (k == N) k = 0;}return k;
}int main()
{int n;scanf("%d", &n);memset(h, 0x3f, sizeof h);while (n--){char op[2];int x;scanf("%s%d", op, &x);int k = find(x);if (*op == 'I') h[k] = x;else{if (h[k] != null) puts("Yes");else puts("No");}}return 0;
}
知識(shí)概覽(字符串哈希)
- 字符串哈希也稱為字符串前綴哈希法,它先預(yù)處理出所有前綴的哈希值。
- 主要思想是用一個(gè)P進(jìn)制的角度把一個(gè)字符串看成一個(gè)數(shù)字。例如一個(gè)字符串"ABCD",假設(shè)A為1,B為2,C為3,D為4,則其哈希值為
,其中P可以取131或13331,Q可以取
,這些是經(jīng)驗(yàn)值,99.99%的情況下不會(huì)出現(xiàn)沖突,不解決沖突。
- 字符串哈希用來(lái)快速判斷兩個(gè)字符串是不是相等。KMP算法可以求循環(huán)節(jié),除此之外,KMP算法不如字符串哈希,字符串哈希確實(shí)簡(jiǎn)單直接。
例題展示
題目鏈接
https://www.acwing.com/problem/content/843/
題解
不用考慮取余,溢出相當(dāng)于取余
。
代碼
#include <iostream>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];ULL get(int l, int r)
{return h[r] - h[l - 1] * p[r - l + 1];
}int main()
{scanf("%d%d%s", &n, &m, str + 1);p[0] = 1;for (int i = 1; i <= n; i++){p[i] = p[i - 1] * P;h[i] = h[i - 1] * P + str[i];}while (m--){int l1, r1, l2, r2;scanf("%d%d%d%d", &l1, &r1, &l2, &r2);if (get(l1, r1) == get(l2, r2)) puts("Yes");else puts("No");}return 0;
}
參考資料
- AcWing算法基礎(chǔ)課