KMP

  我会kmp了!我会kmp了!我会kmp了!

今天发现除了动态规划离我较近的就只剩下字符串一类的了,受不了dp了(开始了字符串的匹配。

打开一篇博客开始看,哇不懂啊,5min秒关博客,学会了,一个月前一直看都看不懂突然会了。。可能这就很神奇了,没有怎么深入深入的推。

直接思考出了kmp的过程实现一下就好了。噩梦2个月前都写了然后wa了,今天又乱打了一遍然后一遍a了,连之前哪错了都不知道,然后5min打完代码直接a。

我也有点小骄傲呢。

直接kmp就行了,没多少细节。认真即可。

#include<bits/stdc++.h>
#include<iomanip>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<algorithm>
#include<ctime>
#include<vector>
#include<queue>
#include<deque>
#include<set>
#include<stack>
using namespace std;
inline long long read()
{
    long long x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const long long maxn=250;
long long n,m;
char a[maxn][maxn],b[maxn][maxn];
long long v[maxn],ans=0,nex[maxn];
void KMP(long long x)
{
    memset(nex,0,sizeof(nex));
    long long j=0;long long tot=strlen(a[x]+1);
    nex[1]=0;
    for(long long i=2;i<=tot;i++)
    {
        while(j&&a[x][j+1]!=a[x][i])j=nex[j];
        if(a[x][j+1]==a[x][i])j++;
        nex[i]=j;
    }
    for(long long k=1;k<=n;k++)
    {
        long long len=strlen(b[k]+1);j=0;//原来以前打的没有清0失误!
        for(long long i=1;i<=len;i++)
        {
            while(j&&a[x][j+1]!=b[k][i])j=nex[j];
            if(a[x][j+1]==b[k][i])j++;
            if(j==tot){ans+=(i-j+1)*v[x];j=nex[j];}
        }
    }
}
int main()
{
    //freopen("1.in","r",stdin);
    n=read();m=read();
    for(long long i=1;i<=m;i++)scanf("%s",a[i]+1);
    for(long long i=1;i<=m;i++)v[i]=read();
    for(long long i=1;i<=n;i++)scanf("%s",b[i]+1);
    for(long long i=1;i<=m;i++)KMP(i);
    printf("%lld
",ans);
}
View Code

有一天幸运也会如期而至。

原文地址:https://www.cnblogs.com/chdy/p/10084539.html