字符串匹配一直是我们都需要面对(做题和工作)的问题,现在此总结三大法:
1.KMP算法:浅谈KMP
2.后缀数组法:后缀数组入门
3.hash大法:
将字符串按位展开并乘上一个质数的幂再取模,极小概率下两字符串不等但hash值等,所以可以认为这种做法是正确的。
参考程序:
#include<cstdio> #include<algorithm> #include<iostream> #define maxn 150000 using namespace std; int pri[4]={11,13,17,19}; const int con=317; const int INF=100000007; int n,m; int a[maxn],b[maxn]; long long h[maxn],xp[maxn]; int main(){ scanf("%d%d",&n,&m); int last; scanf("%d",&last); a[1]=pri[3]; for (int i=2;i<=n;i++){ int x; scanf("%d",&x); if (x>last)a[i]=pri[2]; else if (x==last)a[i]=pri[1]; else a[i]=pri[0]; last=x; } for (int i=n;i>0;i--){ h[i]=h[i+1]*con; h[i]%=INF; h[i]+=a[i]; } xp[0]=1; for (int i=1;i<=n;i++){ xp[i]=xp[i-1]*con; xp[i]%=INF; } scanf("%d",&last); b[1]=pri[3]; for (int i=2;i<=m;i++){ int x; scanf("%d",&x); if (x>last)b[i]=pri[2]; else if (x==last)b[i]=pri[1]; else b[i]=pri[0]; last=x; } long long t1=0,tt=0; for (int i=m;i>1;i--){ t1=t1*con+b[i]; t1%=INF; } tt=t1%INF; int cnt=0; for (int i=1;i<=n;i++){ long long x1=h[i+m]*xp[m-1]%INF; long long x2=h[i+1]-x1; if (x2<0)x2+=INF; if (x2==tt)b[cnt++]=i; } printf("%d\n",cnt); for (int i=0;i<cnt;i++)printf("%d\n",b[i]); return 0; }