字符串哈希

luogu P3370

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
using namespace std;
typedef unsigned long long ull;

int n;
char str[1510];
set<ull> S;

ull str_hash(char str[])					//2^64自然溢出 
{
	int base=131, len=strlen(str);
	ull ans=0;
	for(int i=0; i<len; i++)
		ans=ans*base+ull(str[i]-'a'+1);	 	//或 ans=ans*base+ull(str[i]) 直接使用ASCII码 
	return ans;
}

int main()
{
	scanf("%d", &n);
	for(int i=1; i<=n; i++)	scanf("%s", str), S.insert(str_hash(str));
	printf("%d\n", S.size());				//统计方法还可以将全部哈希值顺序存储到一个数组中,排序后计算不重复值 
	return 0;
}

loj.ac 103

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef unsigned long long ull;
char A[1000010], B[1000010];
ull  H[1000010], hash_b, power[1000010];
const int BASE=131;
ull str_hash(char str[])		              						//2^64自然溢出 
{
    ull ans=0;
    int len=strlen(str);
    for(int i=0; i<len; i++)
        ans=ans*BASE+ull(str[i]-'a'+1);     						//或 ans=ans*BASE+ull(str[i]) 直接使用ASCII码 
    return ans;
}
int main()
{
	int len_A, len_B, nsub, ans=0;
	scanf("%s%s", A, B);
	len_A=strlen(A), len_B=strlen(B), nsub=len_A-len_B+1;			//nsub为最大匹配次数(可匹配字串数量) 
    hash_b=str_hash(B);												//计算匹配串的哈希值 
    power[0]=1;
    for(int i=1; i<=1000000; i++)	power[i]=power[i-1]*BASE;		//计算BASE^n 
	H[1]=ull(A[0]-'a'+1);
	for(int i=2; i<=len_A; i++)	H[i]=H[i-1]*BASE+ull(A[i-1]-'a'+1);	//计算A的前缀的hash值 
	for(int i=1; i<=nsub; i++)	
		if(hash_b==H[i+len_B-1]-H[i-1]*power[len_B])	ans++;		//hash_b和A中所有的子串hash值匹配 
	printf("%d\n", ans);
    return 0;
}
posted @ 2019-05-06 11:36  LFYZOI题解  阅读(147)  评论(0编辑  收藏