思路:字符串hash。對於原串,我們進行Hash,存入unordered_set。在O(n)的時間內就可以將所有的Hash值都算出來。
對於接下來的n串。我們對於每一串我們只需要掃描一邊,看Hash值是否在unordered_set中計數即可。
深深感受到unordered_set 和set的區別。
這是set超時!!
對於這兩個STL。
map的優點:有序。題目如果要求對於有序的查詢會更加有利。但是時間相比較unordered_set會慢一些。
unordered_set 的優點:unordered_set作爲c++11的新特性,有點還是特別的突出的。因爲內部實現了哈希表,因此其查找速度非常的快。在這道題目中非常明顯的展現了出來。而其缺點就是無序。
#include<bits/stdc++.h>
#define debug(a) cout << #a << " " << a << endl
#define LL long long
#define ull unsigned long long
#define PI acos(-1.0)
#define eps 1e-6
const int N=1e6+7;
const int base=233;
using namespace std;
unordered_set<ull> s;
char s1[N],s2[N];
ull p[N];
int len_a,len_b;
void init()
{
len_a=strlen(s1+1);
ull Hash=0;
p[0]=1;
for(int i=1;i<=len_a;i++){
Hash=Hash*base+s1[i]-'0';
p[i]=p[i-1]*base;
}
s.insert(Hash);
for(int i=1;i<=len_a;i++){
Hash=(Hash-(s1[i]-'0')*p[len_a-1])*base+s1[i]-'0';
s.insert(Hash);
}
}
int main ()
{
//yyy_3y
//freopen("1.in","r",stdin);
scanf("%s",s1+1);
init();
int n; scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s2+1);
len_b=strlen(s2+1);
ull Hash=0;
ull ans=0;
for(int i=1;i<=len_a;i++){
Hash=Hash*base+s2[i]-'0';
}
if(s.count(Hash)) ans++;
for(int i=len_a+1;i<=len_b;i++){
Hash=(Hash-(s2[i-len_a]-'0')*p[len_a-1])*base+s2[i]-'0';
if(s.count(Hash)) ans++;
}
printf("%llu\n",ans);
}
return 0;
}
/*
abab
2
ababcbaba
*/