【算法笔记】字符串哈希,STL中的常用容器

文章介绍了字符串哈希算法,通过计算字符串的哈希值来快速比较子串,避免冲突。还提到了C++中的数据结构如vector、pair、queue、priority_queue、stack、deque、set和map的使用方法及其常见操作。
摘要由CSDN通过智能技术生成

字符串哈希

str = “ABCABCDEYXCACWing”

H[0]=0

H[1]=“A”

H[2]=“AB”

H[3]=“ABC”

思路,我们可以把字符串转换成一个数字。最后我们把整个数字对Q取模。把最终的数字映射到从0~Q-1 的一个数。

注意:不能把一个字符映射成0,比如A=0;那么AA,AAA,都是0 这样会引起冲突

整个算法是基于人品足够强。不存在冲突的情况下来考虑的。

经验值:p=131,或者=13331,Q=2^64

此外,我们可以利用所有前缀的哈希求得字串的哈希。

请添加图片描述

小技巧:直接使用unsignlong long 来存储最终的结果,我们就不需要取模了,因为溢出就相当于取模。

例题:ACWing841

#include<iostream>
using namespace std;
const int N=100010;
typedef unsigned long long  ULL;
ULL p[N];
ULL h[N];
ULL q = 131;
char str[N]; 
ULL judge(int l,int r){
	return h[r]-h[l-1]*p[r-l+1];
}


int main(){
	int n;
	cin>>n;
	int m;
	cin>>m;
	cin>>str+1;
	p[0]=1;

	for(int i=1;i<=n;++i){
		p[i]=p[i-1]*q;
		h[i]=h[i-1]*q+str[i];
	}

	
	while(m--){
		int l1,r1,l2,r2;
		cin>>l1>>r1>>l2>>r2;
		if(judge(l1,r1)==judge(l2,r2)){
			cout<<"Yes"<<endl;
		}else{
			cout<<"No"<<endl;
		}
		
	}
	
	
	
	return 0;
}

vector的基本用法

vector a(10,3) 定义一个长度为10的数组,里面每个数长度都是3

a.empty()判断A是否为空。

a.clear() 清空所有元素

用迭代器来遍历vector

for(vector::iterator i =a.begin();i!=a.end();++i)cout<<*i<<" ";

cout<<endl;

for(auto x: a)cout<<x<<" ";

pair<int,string> p

p.first:第一个元素

p.second:第二个元素

支持比较运算

以first为第一关键字,以second为第二关键字。

pair的初始化:

p = make_pair(10,“yxc”)

p={20,“abc”}

string

string a=“”;

a+=c;

size()

empty()

substr(起始位置,长度); 返回的是某个子串,

c_str() 返回的是调用的字符串的字符数组的起始地址。

queue

empty()

push() //向队尾队列中插入一个元素

front()//返回对头元素

back()//返回队尾元素

pop()//弹出队头元素

priority_queue 优先队列,默认是大根堆

push()

top()

pop()

如何实现小根堆?俩种方法。

一种是创建的时候直接插入-x即可。

另一种方式是定义的时候直定义成小根堆。

priority_queue<int,vector,greater>heap;

stack

push()//向栈顶插入一个元素

top()//返回栈顶元素

pop()//弹出栈顶元素

empty()

size()

deque 双端队列(加强版vector)

size()

empty()

clear()

front()

back()

push_back()//队尾插入

pop_back()//队尾弹出

push_front()//向队首插入元素

pop_front()//队首弹出

begin()/end()

set/multiset

set里面不可以有重复元素

支持:

size()

empty()

clear()

multiset里面可以有重复元素

insert()

find()查找一个数

count()返回的是某个数的个数

erase()

​ (1)输入是一个数,删除所有x

​ (2) 输入一个迭代器,删除一个迭代器

lower_bound()/uper_bound()

lower_bound(x)返回的是大于等于x的最小数的迭代器

uper_bound(x)返回的是大于x的最小数的迭代器

map,multimap

insert() 插入的是一个pair

erase()传入的参数是pair或者是迭代器

find()

[]

例如:

map<string,int>a

a[“yxc”]=1;

cout<<a[“yxc”]<<endl;

bitset,压位

就是每个字节存储八位,比正常的数组减少八倍的内存

bitset<1000>s;

~,&,|,^,>>,<<,==,!=,count()返回有多少个1,any/none()

any()判断是否至少有一个1

none()判断是否全为0

set(),把所有位置置1

set(k,v) 将第K位变为V

reset()把所有位变成0

flip()把所有位置取反等价于~

flip(k)把第k位取反。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值