2.2数据结构哈希表

#include <iostream>
#include <cstring>
using namespace std;
const int N = 100003;
int h[N] , e[N] , ne[N] , idx;//h是数组头,e是存的插的链表的值,ne是其下一个的idx

void insert(int x)
{
    int k = (x % N + N) % N;//负数mod之后还是负数,这是为了防止负数出现
    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);//把h全部初始化成空
    while (n -- ){
        char str[2];
        int x;
        scanf("%s%d" , str , &x);
        if(str[0]=='I') insert(x);
        else{
            if(query(x)) printf("Yes\n");
            else printf("No\n");
        }
    }
    return 0;
}

哈希表的拉链法

2.开放寻址法(y总用得较多,因为只用开一个数组)

一共N个数,经验上开2N~3N的数组,先找到大于2N的第一个质数,然后开这么大的数组,定义一个超过数据范围的null,然后把数组全部初始化成0x3f3f3f3f,因为一个int有32位,memset是4位4位来初始化,写成0x3f就变成了0x3f3f3f3f。精华在于find函数,如果h函数包含x,返回的是x所在位置;如果没有,返回的是第一个找到的空坑。

代码如下:

#include <iostream>
#include <cstring>
using namespace std;
const int N = 100003;
int h[N] , e[N] , ne[N] , idx;//h是数组头,e是存的插的链表的值,ne是其下一个的idx

void insert(int x)
{
    int k = (x % N + N) % N;//负数mod之后还是负数,这是为了防止负数出现
    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);//把h全部初始化成空
    while (n -- ){
        char str[2];
        int x;
        scanf("%s%d" , str , &x);
        if(str[0]=='I') insert(x);
        else{
            if(query(x)) printf("Yes\n");
            else printf("No\n");
        }
    }
    return 0;
}

字符串哈希:

把字符串的每个字母看成一个值,以P进制来表示的值,P按经验取131或者13331,字符串ABCD就等于A*P^3+B*P^2+C*P+D,然后对此余一个数Q,一般Q取2^64,我们可以用unsigned long long来存数,相当于取余了。

KMP算法能做的哈希也可以,除了循环节之外。

 

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef unsigned long long ULL;
const int N = 100010 , P = 131;
ULL h[N] , p[N];
int n , m;
char str[N];
int 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++){
        h[i] = h[i-1]*P + str[i];
        p[i] = p[i-1]*P;
    }
    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;
}

e

posted @ 2021-12-04 11:17  乐池  阅读(40)  评论(0)    收藏  举报