题目链接
题意
问在string t中有多少个以string begin为开头,string end为结尾的不相同的连续子串
题解
刚开始的时候因为没学过字符串hash,所以直接把string开了一个set存起来,然后tle满天飞。之后就学了字符串hash,在后面的点照样tle。无奈去膜别人的代码,发现别人不用set,而用unordered_set。去查了一下c++ referenc,发现unordered_set是用hash表储存的,set是用红黑树储存的。在面对数值相差很大的hash值的时候,很明显unordered_set要快很多。。学习了。
#include<unordered_set>
#include<string>
#include<iostream>
#define N 2010
#define LL long long
using namespace std;
string s,a,b;
bool I[N],II[N];
unordered_set<LL> ans;
int main(){
cin>>s>>a>>b;
int n=s.size(),aa=a.size(),bb=b.size();
int longn=aa>bb? aa:bb;
for(int i=0;i<n;++i){
if(s.substr(i,aa)==a) I[i]=1;
if(s.substr(i,bb)==b) II[bb-1+i]=1;
}
LL hashd;
for(int i=0;i<n;++i){
if(I[i]){
hashd=0;
for(int j=i;j<n;++j){
hashd=hashd*2333+s[j];
if(II[j]&&j-i+1>=longn) ans.insert(hashd);
}
}
}
cout<<ans.size();
return 0;
}
附加内容
字符串hash用代码来表示非常简洁,写出来之后直接意会一下就可以了(其实是语文老师下线语言无法组织)。
char s[50];//准备hash的字符串
long long hashd=0;//hash值
int seed;//hash用的种子
for(int i=0;s[i];++i) hashd=hashd*seed+s[i];