MP and KMP

MP 是 KMP 的简单版本,目前以下题目都是MP算法

KMP的原理就不多说了

http://kb.cnblogs.com/page/176818/

(这个模板起始的next数组值为0,不是-1,在模板中,next数组叫f数组)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxn XXX//自己定
char P[maxn] ;
int f[maxn] ;
void getFail ( char *P , int *f )//对子串的处理
{
    int i , j ;
    int m = strlen(P) ;
    f[0] = f[1] = 0 ;
    for( i = 1 ; i < m ; i++ )
    {
        j = f[i] ;
        while( j && P[i] != P[j] )
        {
            j = f[j] ;
        }
        f[i+1] = P[i] == P[j] ? j+1 : 0 ;
    }
}
int find( char *T , char *P , int *f )
{
    int n = strlen( T ) ;
    int m = strlen( P ) ;
    int j , i ;
    getFail( P , f ) ; //预处理匹配串
    for( i = 0 ; i < n ; i++ )
    {
        while( j && P[j] != T[i] )
        {
            j = f[j] ;
        }
        if( P[j] == T[i] ) j++;
        if( j == m ) return i-m;
    }
    return -1 ;//没有匹配到就返回-1
}

基本模板

题目:

poj3461

/*
匹配串<10,000 被匹配串< 1,000,000 最基本的那种
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define maxnt 1000009
#define maxnw 10009
char w[maxnw];
char t[maxnt];
int f[maxnw];
void getFail(char *p, int *f)
{
    int i,j;
    f[0] = f[1] = 0;
    int m = strlen(p);
    for(i = 1; i<m; i++){
        j = f[i];
        while(j && p[j] != p[i]) j = f[j];
        f[i+1] = p[j]==p[i]? j+1 : 0;
    }
}
int findd()
{
    int ww = strlen(w);
    int tt = strlen(t);
    int j = 0;
    int ans = 0;
    for(int i=0; i<tt; i++)
    {
        while(j && t[i] != w[j]){
            j = f[j];
        }
        if(t[i] == w[j]){
            j++;
        }
        if(j == ww){
            ans++; j = f[j];
        }
    }
    return ans;
}
int main()
{
    int T;
    scanf("%d%*c", &T);
    while( T-- ){
        scanf("%s",w);
        scanf("%s",t);
        getFail(w,f);
        int result = findd();
        cout <<result<< endl;
    }
    return 0;
}

poj2406

/*
 has huge input, use scanf instead of cin to avoid time limit exceed
 will not exceed 1 million characters
 求一个串的最大循环串,输出循环次数
*/
#define maxn 1001000
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std;
char str[maxn];
int f[maxn];
void getFail (char *p, int *f)
{
    int j,i;
    int m = strlen(p);
    f[0] = f[1] = 0;
    for(i=1; i<m; i++)
    {
        j = f[i];
        while(j && p[i]!=p[j]){
            j = f[j];
        }
        f[i+1] = p[i]==p[j]? j+1:0;
    }
}
int main()
{
    while(scanf("%s", str ) && str[0]!=‘.‘)
    {
        getFail(str,f);
        int m = strlen(str);
        //cout<<m<<""<<f[m]<<endl;
        if( m % (m-f[m]) == 0 ){
            printf("%d\n", m/(m-f[m]));
        }
        else{
            printf("1\n");
        }
    }
    //cout << "Hello world!" << endl;
    return 0;
}

poj2752

/*
求既是前缀也是后缀的子串长度
1 <= Length of S <= 400000
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define maxn 400009
using namespace std;
char p[maxn];
int f[maxn];
int getans[maxn];
void getFail(char *p, int *f)
{
    int i,j;
    f[0] = f[1] = 0;
    int m = strlen(p);
    for(i = 1; i<m; i++){
        j = f[i];
        while(j && p[j] != p[i]) j = f[j];
        f[i+1] = p[j]==p[i]? j+1 : 0;
    }
}
int Gett(int*getans, char*p)
{
    int countt;
    int last = f[strlen(p)];
    countt = 1;
    getans[0] = strlen(p);
    if(last == 0) {
        return countt;
    }
    else{
        while(last){
            getans[countt++] = last;
            last = f[last];
        }
        return countt;
    }
}
int main()
{
    int countt;
    while(~scanf("%s",p)){
        getFail(p,f);
        countt = Gett(getans, p);
        while(countt){
            printf("%d", getans[--countt]);
            if(countt == 0){
                printf("\n");
            }
            else{
                printf(" ");
            }
        }
    }
    return 0;
}

poj2185

/**
最小覆盖子串(串尾多一小段时,用前缀覆盖)长度为n-next[n](n-pre[n]),n为串长。
论证见这篇博客:http://blog.csdn.net/fjsd155/article/details/6866991
*/
/*行 <= 10,000 列 <= 75*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#define maxnR 10009
#define maxnC 79
using namespace std;
int r,c;
char sarray[maxnR][maxnC];
char carray[maxnC][maxnR];
int fs[maxnR], f[maxnR];
int gcd(int a_,int b_)
{/*要判断大小*/
    int a,b;
    if(a_>b_){
        a = a_; b = b_;
    }
    else{
        a = b_; b = a_;
    }
    return b==0?a:gcd(b,a%b);
}
int gong(int a,int b)
{
    return a*b/gcd(a,b);
}
void getFail(char *p, int *f)
{
    int i,j;
    f[0] = f[1] = 0;
    int m = strlen(p);
    for(i = 1; i<m; i++){
        j = f[i];
        while(j && p[j] != p[i]) j = f[j];
        f[i+1] = p[j]==p[i]? j+1 : 0;
    }
}
int main()
{
    while(~scanf("%d%d",&r, &c)){
        for(int i=0; i<r; i++){
            scanf("%s",sarray[i]);
            //printf("--%s\n",sarray[i]);
            for(int j=0; j<c;j++){
                carray[j][i] = sarray[i][j];
            }

            getFail(sarray[i], f);
            int n = strlen(sarray[i]);
            fs[i] = n - f[n];
        }
        int hang = 1;
        for(int i=0; i<r; i++){
            hang = gong(hang, fs[i]);
        }
        for(int j=0; j<c; j++){
            carray[j][r] = ‘\0‘;
        /*这里出了问题,一开始这句话加在输入行,但是当列比行多,那么我们只保证了r个列串末尾被初始化,不是c个*/
            //printf("--%s\n",carray[j]);
            getFail(carray[j],f);
            int m = strlen(carray[j]);
            fs[j] = m - f[m];
        }
        int lie = 1;
        for(int j=0; j<c; j++){
            lie = gong(lie,fs[j]);
        }
        if(hang > c){
            hang = c;
        }
        if(lie > r){
            lie = r;
        }
        cout << hang*lie << endl;
    }

    return 0;
}

时间: 2024-12-19 23:51:15

MP and KMP的相关文章

[填坑][主线任务]MP&amp;KMP算法

当时一直就没有理解QAQ,觉得会hash就够了,但是想到fail数组有很多神奇的妙用,于是来填这个坑 先讲MP算法: 我就直接说fail数组的含义吧(从0开始字符串下标): fail[i]表示0~i-1这个串的最长border的长度,同时也是重新开始匹配的将要匹配的那个位置下标. 举个小栗子:对于字符串 abcdabd fail[6]=2,即abcdab的最长border的长度为2(ab),匹配失败的时候,下标跳到fail[6](为2)再来匹配,即从‘c’字母开始匹配(因为前边的‘ab’已经匹配

KMP专题总结

KMP算法有两种计算失配函数的方法 未优化过的失配函数 , f[i] 就表示 str[0~i-1] 的公共最长前后缀( 不包括str[0~i-1]本身,比如aaa的最长公共前后缀长度为2 ) , 这个特性必须牢记 从下面的例子应该也可以看出 0  1  2  3  4  5  6  7  8  9  10 str  a  a  a  a  b  b  a  a  b  a  '\0' f   0  0  1  2  3  0  0  1  2  0   1 优化过后的失配函数,虽然匹配的性能要好

hdu6153 A Secret CCPC网络赛 51nod 1277 KMP

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6153 题意: 给出两个字符串S1,S2,求S2的所有后缀在S1中出现的次数与其长度的乘积之和. 思路: CCPC网络赛题解: https://post.icpc-camp.org/d/714-ccpc-2017 http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1277   是一样的 将s1,s2翻转,转化为求前缀在s1中出

UVA 11475 Extend to Palindrome KMP

题目链接:https://vjudge.net/problem/UVA-11475 题意: 给你一个串S 你可以在结尾补充任意数量字母,问最少数量使得新串是回文串 题解: KMP 将S串倒置跑KMP #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls | 1

UVA - 11019 Matrix Matcher hash+KMP

题目链接:https://vjudge.net/problem/UVA-11019 题解: 赶着回寝室 明天写题解 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii

HDU 5918 Sequence I KMP

Sequence I Problem Description Mr. Frog has two sequences a1,a2,?,an and b1,b2,?,bm and a number p. He wants to know the number of positions q such that sequence b1,b2,?,bmis exactly the sequence aq,aq+p,aq+2p,?,aq+(m−1)p where q+(m−1)p≤n and q≥1. In

hdu 3746 Cyclic Nacklace KMP

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3746 题目: Problem Description CC always becomes very depressed at the end of this month, he has checked his credit card yesterday, without any surprise, there are only 99.9 yuan left. he is too distressed

hdu4749 kmp应用

呃,从网上看的题解,然而其实有点地方还没搞懂,先放在这,以后再回来理解. 题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4749 题目:2013 is the 60 anniversary of Nanjing University of Science and Technology, and today happens to be the anniversary date. On this happy festival, school autho

hdu1711 Number Sequence kmp应用

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1711 题目: Problem Description Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M <= 10000, 1 <= N <= 1000000). Your task is to find a number K which m