介绍
哈希一般分为数字哈希和字符串哈希,数字哈希一般使用unordered_map解决,而字符串哈希则需要手写。
简单介绍一下字符串哈希的原理,(数字哈希应该没什么好说的了)
下面是求解hash函数的推导式
![](https://img-blog.csdnimg.cn/img_convert/b5b4acca2a8ca5cc2894b560a371c0c5.gif)
for (int i = 1; i <= n; i++){
ha[i] = (ha[i - 1] * base + a[i] - 'a') % p;
}
那么如何用面的数组ha来推导字符串s[l]到s[r]的哈希值呢?
res = (ha[r] - 1LL * ha[l - 1] * c[r - l + 1] % p + p) % p
查重判断
![](https://img-blog.csdnimg.cn/img_convert/f2b4a4bc65d64613b8adebf9a66fac4e.png)
//查重判断-解法一
#include<bits/stdc++.h>
using namespace std;
const int P = 9999971;
int n, m;
int a[200010], b[200010];
vector<int> c[P];
int main(){
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]);
}
for (int i = 1; i <= m; i++){
scanf("%d", &b[i]);
}
for (int i = 1; i <= n; i++){
c[a[i] % P].push_back(a[i]);
}
int x = 0;
for (int i = 1; i <= m; i++){
int l = c[b[i] % P].size();
bool ok = 0;
for (int j = 0; j < l && !ok; j++){
if (c[b[i] % P][j] == b[i]){
ok = 1;
}
}
if (ok){
x++;
}
}
if (2 * x >= m){
printf("Yes\n");
}
else {
printf("No\n");
}
}
学生信息管理
![](https://img-blog.csdnimg.cn/img_convert/96c57de9cf9a4c449b085519c73a109f.png)
//学生管理
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m;
int a, b, c;
struct node{
int age, tall, num;
};
unordered_map<string, node> h;
int main(){
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++){
string ss;
char ch[20];
scanf("%s", ch);
ss = ch;
node t;
scanf("%d%d%d", &t.age, &t.tall, &t.num);
h[ss] = t;
}
for (int i = 1; i <= m; i++){
string s;
char ch[20];
scanf("%s", ch);
s = ch;
if (h.find(s) == h.end()){
printf("-1 -1 -1\n");
}
else {
printf("%d %d %d\n", h[s].age, h[s].tall, h[s].num);
}
}
}
求众数
![](https://img-blog.csdnimg.cn/img_convert/6db4a7ab5e1f43ada93d5e232b11137a.png)
//求众数
#include<bits/stdc++.h>
using namespace std;
int n;
int a[200010];
unordered_map<int, int> c;
int main(){
scanf("%d", &n);
for (int i = 1; i <= n; i++){
int x;
scanf("%d", &x);
c[x]++;
}
int x = 0, l = 0;
for (auto it : c){
if (it.second > x){
x = it.second, l = 0;
}
if (it.second == x){
a[++l] = it.first;
}
}
sort(a + 1, a + l + 1);
for (int i = 1; i <= l; i++){
printf("%d ", a[i]);
}
printf("\n");
}
构造最长回文数组
![](https://img-blog.csdnimg.cn/img_convert/a7964fd24af04ab785799692234289f0.png)
//构造最长回文数组
#include<bits/stdc++.h>
using namespace std;
int n;
int a[200010];
unordered_map<int, int> c;
int main(){
scanf("%d", &n);
for (int i = 1; i <= n; i++){
int x;
scanf("%d", &x);
c[x]++;
}
int ans = 0, t = 0;
for (auto it : c){
if (it.second > 1){
ans += (it.second / 2) * 2;
}
if (it.second & 1){
t = 1;
}
}
printf("%d\n", ans + t);
}
小蜗的疑问-单哈希
![](https://img-blog.csdnimg.cn/img_convert/853528dab1a542849402b7ad90d806ce.png)
//小蜗的疑问-单哈希
#include<bits/stdc++.h>
using namespace std;
const int p = 9999971, base = 101;
int n, m;
char a[200011], b[200011];
int ha[200011], hb, c[200011];
int main(){
scanf("%d%d", &n, &m);
scanf("%s%s", a + 1, b + 1);
c[0] = 1;
for (int i = 1; i <= 200000; i++){
c[i] = c[i - 1] * base % p;
}
for (int i = 1; i <= n; i++){
ha[i] = (ha[i - 1] * base + a[i] - 'a') % p;
}
for (int i = 1; i <= m; i++){
hb = (hb * base + b[i] - 'a') % p;
}
int ans = 0;
for (int i = 1; i + m - 1 <= n; i++){
if ((ha[i + m - 1] - 1LL * ha[i - 1] * c[m] % p + p) % p == hb){
++ans;
}
}
printf("%d\n", ans);
}
//小蜗的疑问-双哈希
#include<bits/stdc++.h>
using namespace std;
const int p = 9999971, base = 101;
const int p2 = 9999973, base2 = 137;
int n, m;
char a[200011], b[200011];
int ha[200011], hb, c[200011];
int ha2[200010], hb2, c2[200010];
int main(){
scanf("%d%d", &n, &m);
scanf("%s%s", a + 1, b + 1);
c[0] = 1, c2[0] = 1;
for (int i = 1; i <= 200000; i++){
c[i] = c[i - 1] * base % p;
c2[i] = c2[i - 1] * base2 % p2;
}
for (int i = 1; i <= n; i++){
ha[i] = (ha[i - 1] * base + a[i] - 'a') % p;
ha2[i] = (ha2[i - 1] * base2 + a[i] - 'a') % p2;
}
for (int i = 1; i <= m; i++){
hb = (hb * base + b[i] - 'a') % p;
hb2 = (hb2 * base2 + b[i] - 'a') % p2;
}
int ans = 0;
for (int i = 1; i + m - 1 <= n; i++){
if ((ha[i + m - 1] - 1LL * ha[i - 1] * c[m] % p + p) % p == hb &&
(ha2[i + m - 1] - 1LL * ha2[i - 1] * c2[m] % p2 + p2) % p2 == hb2 ){
ans++;
}
}
printf("%d\n", ans);
}