{模版}KMP字符串匹配

判断B串是否为A串的字串
如果是,输出 x 使A[x..x+m1]=B[1..m]
定义

模板题 JZOJ_Junior1381

const
        maxn=1001000;
        maxm=1001000;
var
        n,m:longint;
        i,j,l:longint;
        a,b:ansistring;
        p:array[0..maxm] of longint;
begin
        readln(a);n:=length(a);
        readln(b);m:=length(b);
        p[1]:=0;j:=0;
        for i:=2 to m do
        begin
                while(j > 0)and(b[j + 1] <> b[i])do j:=p[j];
                if (b[j + 1] = b[i]) then inc(j);
                p[i]:=j;
        end;

        j:=0;
        for i:=1 to n do
        begin
                while (j > 0) and (b[j + 1] <> a[i]) do j:= p[j];
                if (b[j + 1] = a[i]) then inc(j);
                if (j = m) then
                begin
                        writeln(i - m + 1);
                        halt;
                end;
        end;
        writeln('-1');
end.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define oo 2139062143
#define sqr(x) ((x)*(x))
#define abs(x) (((x)>=0)?(x):(-(x)))
#define max(x,y) (((x)>(y))?(x):(y))
#define min(x,y) (((x)<(y))?(x):(y))
#define fo(i,x,y) for (int i = (x);i <= (y);++ i)
#define fd(i,x,y) for (int i = (x);i >= (y);-- i)
#define fm(i,x) for (int i = las[x];i;i = e[i].nex)
using namespace std;
typedef double db;
typedef long long ll;
const int LEN = 1001000;
int n,m;
char a[LEN],b[LEN];
int p[LEN];
int main()
{
    scanf("%s\n%s",a + 1,b + 1);
    n = strlen(a + 1),m = strlen(b + 1);
    int j = 0;
    p[1] = 0;
    fo(i,2,m)
    {
        while (b[i] != b[j + 1] && j) j = p[j];
        if (b[i] == b[j + 1]) ++ j;
        p[i] = j;
    }
    j = 0;
    fo(i,1,n)
    {
        while (a[i] != b[j + 1] && j) j = p[j];
        if (a[i] == b[j + 1]) ++ j;
        if (j == m)
        {
            printf("%d\n", i - m + 1);
            return 0;
        }
    }
    printf("-1");
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值