第二章 数据结构(三)

文章介绍了哈希表的概念,包括拉链法和开放寻址法解决冲突的方法,并提供了C++代码示例。此外,文章还提到了字符串哈希及其在判断子串相等中的应用。最后,对STL中的几种容器如vector、string、queue、stack、deque、set、map进行了简要介绍。
摘要由CSDN通过智能技术生成

本节内容:哈希表与STL简介。

一、哈希表

存储结构(解决映射冲突的方法:开放寻址法、拉链法)、字符串哈希的方式。

哈希表可以通过函数的映射关系f(x)快速找到一个数x是否在一个集合当中存在过,好的哈希函数时间复杂度可以近似为O(1),而暴力的做法则是需要遍历一遍数组,时间复杂度最慢为O(n)。这是一个典型的用空间换时间的方法,一个好的哈希函数也是关键,可以使得冲突最小。

(1)、拉链法

在冲突的位置加上一个单链表。

acwing840

#include<iostream>
#include<cstring>
using namespace std;

const int N = 100003;

int h[N],e[N],ne[N],idx = 0;

void Insert(int x){
    int k = (x % N + N) % N;
    e[idx] = x;
    ne[idx] = h[k];
    h[k] = idx++;
    
}
bool find(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[0] == 'I'){
            Insert(x);
        }
        else{
            if(find(x)) printf("Yes\n");
            else printf("No\n");
        }
    }
    return 0;
}

(2)、开放寻址法

将数组的大小设置成集合大小的两到三倍最好,再取大于等于这个数的最小质数

#include<iostream>
#include<cstring>
using namespace std;
//ACM中常用的无穷大常量——0x3f3f3f3f,0x3f3f3f3f的十进制是1061109567,是10^9级别的,而一般场合下
//的数据都是小于10^9的,所以它可以作为无穷大使用而不致出现数据大于无穷大的情形。
const int N = 200003,null = 0x3f3f3f3f;

int h[N],idx = 0;


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[0] == 'I'){
            
            h[k] = x;
        }
        else{
            if(h[k] != null) printf("Yes\n");
            else printf("No\n");
        }
    }
    return 0;
}

二、字符串哈希

字符串哈希可能会有冲突,在p,q取特定值时,基本不会出现冲突。 

可以利用数字来表示一个特定的字符串,再利用前缀和来计算每一个子串的哈希值,利用哈希值是否相等来判断子串是否相等。注意比较的时候还要将小的值呈上p的(r-l+1)次方,使其左移。具体公式如下:

                                                        h[i] = h[i] \times p + str[i]

                        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        h[R]-h[L]\times p^{R-L+1}

用unsigned long long来存储所有的h,如果数据溢出相当于取模。 

#include<iostream>
#include<cstring>
using namespace std;

typedef unsigned long long ULL;
const int N = 100010,P = 131;

int n,m;
ULL h[N],p[N];
char str[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++){
         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;
}

三、STL简介

1、vector:

变长数组,倍增的思想

2、string:

字符串,substr,c_str()

3、queue,priority_queue:

push(),pop(),front()

4、stack:

push(),top(),pop()

5、deque:

双端队列

6、set,map,multiset,multimap:

7、unordered_set,unordered_map,unordered_multiset,

unordered_multimap:

hash表实现

8、bitset:

压位 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值