扩展KMP总结(模板题hdu2594)

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 16:26   3308   0

参考介绍:点击打开链接 点击打开链接

模板题:hdu2594 (扩展KMP)

http://acm.hdu.edu.cn/showproblem.php?pid=2594

题目大意:给定两个字符串,在第一个字符串中找到一个最大前缀作为第二个字符串的后缀

思路:将S1作为模式串 然后在s2中寻找,求出s1的next数组,nxt[i]:x[i...m-1]与x[0...m-1]的最长公共前缀。同时求出s2的extend数组,extend[i]:y[i...n-1]与x[0...m-1]的最长公共前缀

借鉴kuangbin的模板:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
/*
* 扩展KMP算法
*/
//nxt[i]:x[i...m-1]与x[0...m-1]的最长公共前缀
//extend[i]:y[i...n-1]与x[0...m-1]的最长公共前缀
int nxt[100050];
int extend[100050];
char s[100050], t[100050];
void pre_EKMP(char x[],int m,int nxt[])
{
 nxt[0]=m;
 int j=0;
 while(j+1<m && x[j]==x[j+1]) j++;
 nxt[1]=j;
 int k=1;
 for(int i=2;i<m;i++)
 {
  int p=nxt[k]+k-1;
  int L=nxt[i-k];
  if(i+L<p+1)nxt[i]=L;
  else
  {
   j=max(0,p-i+1);
   while(i+j<m && x[i+j]==x[j])j++;
   nxt[i]=j;
   k=i;
  }
 }
}
void EKMP(char x[],int m,char y[],int n,int nxt[],int extend[])
{
 pre_EKMP(x,m,nxt);
 int j=0;
 while(j<n && j<m && x[j]==y[j]) j++;
 extend[0]=j;
 int k=0;
 for(int i=1;i<n;i++)
 {
  int p=extend[k]+k-1;
  int L=nxt[i-k];
  if(i+L<p+1)
   extend[i]=L;
  else
  {
   j=max(0,p-i+1);
   while(i+j<n && j<m && y[i+j]==x[j]) j++;
   extend[i]=j;
   k=i;
  }
 }
}

int main()
{
    while(cin >> s >> t)
    {
     int slen = strlen(s),tlen = strlen(t);
        EKMP(s,slen,t,tlen,nxt,extend);
        int ans = 0;

        for(int i = tlen - 1, j = 0; j < slen; j++, i--)
        {
            if(extend[i] == tlen - i)
            {
                ans = max(ans, extend[i]);
            }
        }
        if(ans)
        {
            for(int i = 0; i < ans; i++)
                cout << s[i];
            cout << " ";
        }
        cout << ans <<endl;
    }
    return 0;
}




分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP