cf之kmp匹配稍稍改一改

看样例就知道要干嘛了

http://codeforces.com/contest/1200/problem/E

每次我们用新的串和答案串匹配,答案串的匹配位置是max(0,(int)ans.size()-(int)s.size()),这样可以降低时间复杂度。答案串是S,新串是T。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1000000+66;
const ll mod=1e9+7;
int n;
string s[maxn];
string ans;
int nexts[maxn];
void getnexts(string t)
{
    int len=t.size();
    int i=0;
    int j=-1;
    nexts[0]=-1;
    while(i<len)
    {
        if(j==-1||t[i]==t[j])
        {
            i++;
            ++j;
            if(t[i]!=t[j])
                nexts[i]=j;
            else
                nexts[i]=nexts[j];
        }
        else
        {
            j=nexts[j];
        }
    }
}
int kmp(string &s,string &t,int pos)//s是答案串
{
    int i=pos;//
    int j=0;
    int sl=s.size();
    int tl=t.size();
    while(i<sl)
    {
        if(j==-1||s[i]==t[j])
        {
            ++i;
            ++j;
        }
        else
        {
            j=nexts[j];
        }
    }
    return j;
}
void add(string s)
{
    getnexts(s);
    int pos=kmp(ans,s,max(0,(int)ans.size()-(int)s.size()));
    for(int i=pos; i<s.size(); i++)
    {
        ans.push_back(s[i]);
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        cin>>s[i];
    }
    ans=s[1];
    for(int i=2; i<=n; i++)
    {
        add(s[i]);
    }
    cout<<ans;
}

  

原文地址:https://www.cnblogs.com/hgangang/p/11830722.html

时间: 2024-10-29 19:05:51

cf之kmp匹配稍稍改一改的相关文章

poj 2406 Power Strings KMP匹配

对于数组s[0~n-1],计算next[0~n](多计算一位). 考虑next[n],假设t=n-next[n],如果n%t==0,则t就是问题的解,否则解为1. 这样考虑: 比如字符串"abababab", a  b a b a b a b * next     -1 0 1 2 3 4 5 6  7 考虑这样的模式匹配,将"abababab#"当做主串,"abababab*"当做模式串,于是进行匹配到n(n=8)时,出现了不匹配: 主串   

KMP匹配

字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"? 许多算法可以完成这个任务,Knuth-Morris-Pratt算法(简称KMP)是最常用的之一.它以三个发明者命名,起头的那个K就是著名科学家Donald Knuth. 这种算法不太容易理解,网上有很多解释,但读起来都很费劲.直到读到Jake Boxer的文章,我才真正理解这种算法.下面,我用自己的语言

KMP(匹配)

Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Input 输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样.花纹条和小饰条不会超过1000个字符长.如果遇见#字符,则不再进行工作. Output 输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间

KMP匹配 (1)

---恢复内容开始--- 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"? 许多算法可以完成这个任务,Knuth-Morris-Pratt算法(简称KMP)是最常用的之一.它以三个发明者命名,起头的那个K就是著名科学家Donald Knuth. 这种算法不太容易理解,网上有很多解释,但读起来都很费劲.直到读到Jake Boxer的文章,我才真正理解这种

CF 631D KMP/Z

给定两个压缩形式的字符串,如a3b5a4k7这样的形式 问A在B中出现次数. 分类讨论,如果A是只有一种字符的,则答案数量可能很大,但计算也很简单,直接看B的每一个字符,答案累加上cnt2-cnt1+1 如果A不是单字符的,则答案至多是B的压缩之后长度的数量级. 不考虑A的第一个字符,用KMP或者Z函数来计算A的出现情况,如果匹配长度为lenA-1,则检查是否该匹配的第一个字符与A[0]相等且数量大于A[0]的数量,如果匹配长度为lenA-2,则检查是否下一个字符与A最后一个字符是相等的,且数量

流动python - 字符串KMP匹配

首先我们看一下简单的字符串匹配. 你可以把文本字符串s固定,模式字符串p从s对齐的左边缘,作为承担部分完全一致,匹配成功,失败将是模式字符串p整体向右1地点,继续检查对齐部分,重复. #朴素匹配 def naive_match(s, p): m = len(s); n = len(p) for i in range(m-n+1):#起始指针i if s[i:i+n] == p: return True return False 关于kmp算法,讲的最好的当属阮一峰的<字符串匹配的KMP算法>.

CF 126B KMP/Z_match

大意:给一个字符串,问最长的既是前缀又是后缀又是中缀(这里指在内部出现)的子串. 我自己的做法是用KMP的next数组,对所有既是前缀又是中缀的位置计数,再从next[n]开始走next,也即枚举所有既是前缀又是后缀的子串,看cnt[i]是否大于0,如果大于0则说明作为中缀出现过(也即有大于i的某个位置的next为i) 1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #include

HDU - 1686 Oulipo KMP匹配运用

HDU - 1686 Oulipo Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status Description The French author Georges Perec (1936?1982) once wrote a book, La disparition, without the letter 'e'. He was a member of the Ouli

手算KMP匹配的Next值和Nextval值

文章作者:姜南(Slyar) 文章来源:Slyar Home (www.slyar.com) 转载请注明,谢谢合作. KMP 算法我们有写好的函数帮我们计算 Next 数组的值和 Nextval 数组的值,但是如果是考试,那就只能自己来手算这两个数组了,这里分享一下我的计算方法吧. 计算前缀 Next[i] 的值: 我们令 next[0] = -1 .从 next[1] 开始,每求一个字符的 next 值,就看它前面是否有一个最长的"字符串"和从第一个字符开始的"字符串&qu