题目链接:http://poj.org/problem?id=1200
题意:给出不同字符个数不超过NC的一个字符串,问长度为n的不同子串有多少个?
思路:因为母串字符种类不超过NC,所以将母字符串转化成NC进制的一串数字串,因为母串的所有不同字串个数不超过16 million,所以枚举每个长度为N的子串的哈希值可过
注意:虽然子串的总数不超过16 million,但是hash值会大于16 million。
代码:
#include<iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
int const MAXN = 1600000+7;
int n,nc;//NC为text可能的最多有NC个字符不同,所以将字符串转化成NC进制,给text出现的字符赋予对应的数字,从0~NC,然后Hash
char T[MAXN];
bool hash[20000007];//hash表开到最大==,小了可能挂
int temp,count;
int num[MAXN];
int Hash()
{
count = 0;
int m = strlen(T);
for(int i = 0;i<m-n+1;i++)
{
temp = 0;
for(int j = i;j<i+n;j++)
{
temp = (temp*nc+(num[T[j]]))%20000007;
}
if(!hash[temp])
{
hash[temp] = 1;
count++;
}
}
return count;
}
int main()
{
while(~scanf("%d%d",&n,&nc))
{
scanf("%s",T);
memset(hash,0,sizeof(hash));
memset(num,0,sizeof(num));
int nums = 0;
for(int i = 0;i<strlen(T);i++)
{
if(!num[T[i]])num[T[i]] = nums++;
}
cout<<Hash()<<endl;
}
return 0;
}