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;
}

猜你喜欢

转载自blog.csdn.net/zhanglili1597895/article/details/112976613