9.10A

题目链接https://vjudge.net/problem/2638259/origin

String matching is a common type of problem in computer science. One string matching problem is as following:

Given a string [Math Processing Error]s[0…len−1], please calculate the length of the longest common prefix of [Math Processing Error]s[i…len−1] and [Math Processing Error]s[0…len−1] for each [Math Processing Error]i>0.

I believe everyone can do it by brute force.
The pseudo code of the brute force approach is as the following:

在这里插入图片描述

We are wondering, for any given string, what is the number of compare operations invoked if we use the above algorithm. Please tell us the answer before we attempt to run this algorithm.
Input
The first line contains an integer [Math Processing Error]T, denoting the number of test cases.
Each test case contains one string in a line consisting of printable ASCII characters except space.

  • [Math Processing Error]1≤T≤30

  • string length [Math Processing Error]≤106 for every string
    Output
    For each test, print an integer in one line indicating the number of compare operations invoked if we run the algorithm in the statement against the input string.
    Sample Input
    3
    Happy_New_Year
    ywwyww
    zjczzzjczjczzzjc
    Sample Output
    17
    7
    32

题目大意,有一个字符串,i=0,j=1,k=0,S【i+k】和S【j+k】 比较,如果相同,k++,再次比较,直到S【i+k】和S【j+k】不相同,j++,再次进行比较,求最终字符串的比较次数。
扩展kmp的模板题
贴上代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000010;
int nxt[maxn];
char s[maxn];
ll  solve(char str[])
{
    ll ans = 0;
    int i=0,j,po,len=strlen(str);
    nxt[0]=len; 
    while(str[i]==str[i+1] && i+1<len) i++; nxt[1]=i; 
    ans += nxt[1];
    if(nxt[1] != len - 1) ans++;
    po=1; 
    for(i=2;i<len;i++)
    {
        if(nxt[i-po]+i < nxt[po]+po) 
            nxt[i]=nxt[i-po];
        else 
        {
            j = nxt[po]+po-i;
            if(j<0) j=0; 
            while(i+j<len && str[j]==str[j+i]) j++; nxt[i]=j;
            po=i; 
        }
        ans += nxt[i];
        if(nxt[i] != len - i) ans++;
    }
    return ans;
}
int main()
{
    //freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%s",s);
        printf("%lld\n", solve(s));
    }
    return 0;
}

EKMP,扩展kmp。
解决的问题:定义母串S和子串T,S的长度为n,T的长度为m,求母串S中每一个后缀与子串T的最长前缀总数。
也就是说,设有extend数组:extend[i]表示T与S[i,n-1]的最长公共前缀,要求出所有extendi。
(注意到,如果存在若干个extend[i]=m,则表示T在S中完全出现,且是在位置i出现,这就是标准的KMP问题,所以一般将它称为扩展KMP算法。)
找到一篇写的很好的博客,讲解EKMP比较完整,附上链接:https://www.jianshu.com/p/107e47994d49

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值