题意:给你一个包含m种字符的字符串,求长度为n的不同子串有多少个,有nc个不同字符。
思路:这道题hash其实只是最简单的hash,无非就是暴力搜索,将n个字符子串的每个字符用hash对应成一个数字,然后用nc+1作为进制,来构造一个数,然后判断这个数是否出现过了。
这里我一开始怕空间可能会超,因为它没给出具体的n的范围,所以我用set,这样虽然节省了空间,但时间复杂度变成了o(nlogn),超时!,于是只好用第二次hash,直接暴力构造一个很大的数组来存储是否出现过该字符子串,过了!!时间复杂度为o(n)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
int hash[256];
char f[10000000];
long long ans,temp;
//set<long long> p;
char s[10000000];
int main()
{
//FILE *fp=fopen("t.txt","r");
int n,nc;
while(scanf("%d%d%s",&n,&nc,s)!=EOF)
{
//p.clear();
int len=strlen(s);
int cnt=1;
memset(hash,0,sizeof(hash));
memset(f,0,sizeof(f));
for(int i=0;i<len;i++)
{
if(hash[s[i]]==0)
{
hash[s[i]]=cnt++;
}
}
for(int i=0;i+n-1<len;i++)
{
temp=0;
for(int j=i;j<=i+n-1;j++)
{
temp*=(nc+1);
temp+=hash[s[j]];
}
/*if(p.count(temp)==0)
{
ans++;
p.insert(temp);
}*/
if(!f[temp])
{
f[temp]=1;
ans++;
}
}
printf("%lld\n",ans);
}
return 0;
}