题意:给出不同字符个数和子串长度,判断有多少个不同的子串
思路:字符串hash。
用字符串函数+map为什么会超时呢??
代码:
#include <iostream> #include <cstring> #include <stdio.h> using namespace std; const int N=16000005; //题目给出子串的最大和不超过16M const int NUM=257; bool hash[N]; int m[NUM]; char str[1000000]; int main() { int n,nc,i,j,sum,seed=0,ans=0; memset(hash,false,sizeof(hash)); memset(m,0,sizeof(m)); memset(str,' ',sizeof(str)); cin>>n>>nc>>str; for(i=0;' ' != str[i];++i) { if(!m[str[i]]) //将每个字符赋值为相应进制的数 m[str[i]]=++seed; if(seed == nc) break; } int len=strlen(str); for(i=0;i<=len-n;++i) { sum=0; for(j=0;j<n;++j) //将字符串str[i],..,str[i+n-1]变为一个nc进制的整数,来判断是否重复出现过 sum=sum*nc+m[str[i+j]]-1; if(!hash[sum]) { hash[sum]=true; ++ans; } } cout<<ans<<endl; return 0; }
hash函数+map:
#include<iostream> #include<cstring> #include<cstdio> #include<map> using namespace std; #define MAXN 16000010 char str[MAXN]; map<int,bool> hash; int n,nc; unsigned int hashValue(char *str , char *end) { unsigned int hash = 0; int i; for (i=0; str < end; i++) { if ((i & 1) == 0) { hash ^= ((hash << 7) ^ (*str++) ^ (hash >> 3)); } else { hash ^= (~((hash << 11) ^ (*str++) ^ (hash >> 5))); } } return (hash & 0x7FFFFFFF); } int main() { while(scanf("%d%d",&n,&nc)!=EOF) { scanf("%s",str); int len=strlen(str); char *s=str; char *t=s+len; for(;s<=t-n;s++) { int v=hashValue(s,s+n); hash[v]=true; } printf("%d ",hash.size()); } return 0; }