poj3461 Oulipo —— KMP

题目链接:http://poj.org/problem?id=3461


代码如下:

 

#include<cstdio>//poj 3461 kmp
#include<cstring>

using namespace std;

char s1[1000005], s2[10005];
int len1, len2,next[10005];

void getnext()
{   //next数组其实是:当前字符匹配失败时,小字符串退回到合适的位置,然后继续匹配。
    int i = 0, j = -1;
    next[0] = -1;

    while(i<len2)
    {
        if(j==-1 || s2[i]==s2[j])//如果没有前缀或 前缀等于后缀,则进入
        {
            i++; j++; //先自增1
            if(s2[i]==s2[j])  //如果继续相等,则next[i]为当j不匹配又退回的合适位置。
                next[i] = next[j];
            else  //如果不相等,则next[i]就等于j
                next[i] = j;
        }
        else j = next[j];
    }
}

int kmp()
{
    int sum = 0, i = 0, j = 0;
    getnext();
    while(i<len1)  //i只会增加(线性),而j会回溯反复进行匹配
    {	/*当j=-1时,表明上一次连第一个字符都不相等,则i会继续前进,j经过回溯又前进,还是变为第一个字符。
	      下次循环继续匹配第一个字符*/
        if(j==-1 || s1[i]==s2[j])
        {
            i++; j++;
            if(j==len2)
            {
                sum++;
                j = next[j];
            }
        }
	/*如果当前字符不匹配,i不变,等待下一个匹配。而j退回到合适的位置。
	  下次循环继续与当前i进行匹配*/
        else j = next[j];
    }
    return sum;
}

int main()
{
    int T;
    scanf("%d\n",&T);
    while(T--)
    {
        scanf("%s%s",s2,s1);
        len1 = strlen(s1); len2 = strlen(s2);
        printf("%d\n",kmp());
    }
    return 0;
}


 

转载于:https://www.cnblogs.com/DOLFAMINGO/p/7538781.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值