ybtoj【字符串算法】2章1题&&P3370【字符串哈希】

字符串

题目

字符串哈希


题目

字符串哈希的模板题
字符串哈希一般方法是将每一个字符与一个数字建立对应,并设定进制,求值取余后作为哈希值
但是字符串哈希绝不仅仅如此,还有一点,那就是哈希自动机双哈希
实现方法:
使用两个哈希数组,建立两个不同的哈希映射,只有两者都出现时才算出现过
具体实现请看代码(注意不要MLE了):

code:

#include<cstdio>
#include<cstring>
#include<iostream>
#define m1 1000007
#define m2 1000009
using namespace std;
int n,s=0,x,y;
string t[10010],a[m1],b[m2];
int sum(char s)
{
	if(s>='A'&&s<='Z')return s-'A'+1;
	if(s>='a'&&s<='z')return s-'a'+27;
	return s-'0'+55;
}//建立映射
int h1(string x)
{
	int ans=0;
	for(int i=0;i<x.size();i++)ans=((ans*97%m1)+sum(x[i]))%m1;
	return ans;
}
int h2(string x)
{
	int ans=0;
	for(int i=0;i<x.size();i++)ans=((ans*89%m2)+sum(x[i]))%m2;
	return ans;
}//两套哈希函数
int w1(string x)
{
	int q=h1(x),i=0;
	while(i<m1&&a[(q+i)%m1]!=""&&a[(q+i)%m1]!=x)i++;
	return (q+i)%m1;
}
int w2(string x)
{
	int q=h2(x),i=0;
	while(i<m2&&b[(q+i)%m2]!=""&&b[(q+i)%m2]!=x)i++;
	return (q+i)%m2;
}//分别查询
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		cin>>t[i];
		x=w1(t[i]),y=w2(t[i]);//卡常
		if(a[x]!=t[i]||b[y]!=t[i])++s,a[x]=t[i],b[y]=t[i];//重复不用再次插入
	}
	printf("%d",s);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值