• 【HDOJ2087】剪花布条(KMP)


    problem

    • 给定字符串A,B。求串A中可以分割出多少个互不相同的串B(不能重叠)。

    solution

    模板题,没啥好说的。
    KMP匹配:如果成功,就把j==0,从头开始匹配,答案累加。

    codes

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 1010;
    
    char a[maxn], b[maxn];
    int n, m, Next[maxn], f[maxn];
    
    void pre(){
        Next[1] = 0;
        int j = 0;
        for(int i = 1; i < m; i++){
            while(j>0 && b[i+1]!=b[j+1])j = Next[j];
            if(b[i+1]==b[j+1])j++;
            Next[i+1] = j;
        }
    }
    int kmp(){
        int ans = 0, j = 0;
        for(int i = 0; i < n; i++){
            while(j>0 && a[i+1]!=b[j+1])j = Next[j];
            if(a[i+1]==b[j+1])j++;
            f[i+1] = j;
            if(j==m)ans++, j = 0;
        }
        return ans;
    }
    
    int main(){
        while(cin>>a+1){
            if(a[1]=='#')break;
            scanf("%s",b+1);
            n = strlen(a+1);
            m = strlen(b+1);
            pre();
            printf("%d
    ",kmp());
        }
        return 0;
    }

    KMP

    介绍:

    字符串匹配问题:给定主串A和模式串B,求所有B在A中出现的位置。
    传统做法:枚举A串从什么位置开始与B串匹配,然后验证是否匹配。最坏情况A=”aaaaaaaaaaaaaaab”,B=”aaaaaab”,复杂度O(mn)。
    KMP:最坏情况复杂度O(n)

    具体:
    本质原理:

    考虑情况(当前i==5):

    i = 1 2 3 4 5 6 7 8 9
    A = a b a b a b a a b a b
    B = a b a b a c b
    j = 1 2 3 4 5 6 7 8 9

    对于下一个,不再匹配了。传统做法就是把B右移一位继续重头比较。
    但是作为一个人,我一眼就看出了右移一位也不行,,,,于是,我们移到他下一个匹配的位置(最长的相同前缀和后缀)在开始比较。并且最好是这个匹配的长度尽可能长。

    i = 1 2 3 4 5 6 7 8 9
    A = a b a b a b a a b a b
    B =     a b a b a c b
    j =     1 2 3 4 5 6 7 8 9

    再考虑到,B移动后的位置,相对A而言的位置关系,其实是和B移动前的位置关系是一样的(因为之前的时候AB匹配上了,所以是字母是完全一样的)。所以就变成了关于B的自我匹配,具体见下方。

    两个步骤:

    1、对模式串B进行自我匹配:求一个数组next,其中next[i]表示”B中以i结尾的非前缀子串”与“B的前缀”能匹配的最大长度。next[i]=max{j},j<iA[ij+1,i]=A[1,j]
    2、对字符串A与B进行匹配:求一个数组f,其中f[i]表示”A中以i结尾的子串”与“B的前缀”能够匹配的最长长度。(当长度为B.size()时即得到答案)

    具体求法:

    1、求next:
    咕咕咕

  • 相关阅读:
    获取SqlServer数据库、表(字段、索引..)、视图、存储过程等信息脚本
    C# 资源Resources.resx中文件的获取、读取及复制
    C# 解锁从互联网下载的需要右键属性“解除锁定”的文件
    SqlServer根据生日计算年龄,精确到年(岁)月日小时分秒
    PHP设计模式—模板方法模式
    YII2中beforeSave和TimestampBehavior的使用,自动更新创建时间,更新时间
    YII2中like查询单边匹配%
    开发中 利用 spring利用扩展点 applicationContextAware,BeanNameAware实现模板+策略模式
    Spring RestTemplate调用接口乱码解决
    设计模式学习
  • 原文地址:https://www.cnblogs.com/gwj1314/p/10200110.html
Copyright © 2020-2023  润新知