zoukankan      html  css  js  c++  java
  • hdu 1686 Oulipo (KMP)(计算模式串匹配的次数——与已匹配的字串可以有交集)

    <题目链接>

    题目大意:

    输入一个T,表示有T组测试数据;

    每组测试数据包括一个字符串W,T,T的长度$le10^6$,$W$的长度$le 10^4$,计算W匹配到T中成功的次数;

    需要注意的是:

    第一次将匹配成功的位置得到后,若从匹配到的位置开始算起,会超时,实际上没必要,每次模式串匹配成功时,都将个数+1,然后从next数组的下一位继续开始匹配,直至待匹配串结束

    代码如下:实际上就是将kmp裸题稍微改一下。

    若两个不同的匹配没有交集则j=0,若存在交集则j=next[j]

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N1 = 1e6+5, N2 = 1e4+5;
    int nxt[N2];
    char str1[N1],str2[N2];
    int cnt;          //匹配的子串个数
    
    inline void get_nxt(int len2){
        int i = 0, j = -1;
        nxt[0] = -1;
        while (i<len2){
            if (j == -1 || str2[i] == str2[j])nxt[++i]=++j;
            else j = nxt[j];
        }
    }
    inline void kmp(int len1, int len2){
        int i = 0, j = 0;
        get_nxt(len2);
        while (i<len1){
            if (j == -1 || str1[i] == str2[j])++i,++j;
            else j = nxt[j];
            if (j == len2)++cnt,j=nxt[j];                //找到一个匹配的串后,模式串的起点从nxt数组下一个点继续匹配    
        }
    }
    int main(){
        int n;scanf("%d", &n);getchar();
        int len1,len2;
        while (n--){
            gets(str2);gets(str1);
            len1 = strlen(str1);
            len2 = strlen(str2);
            cnt = 0;
            kmp(len1, len2);
            printf("%d
    ", cnt);
        }
    }
  • 相关阅读:
    P4715 【深基16.例1】淘汰赛
    P4913 【深基16.例3】二叉树深度
    P1478 陶陶摘苹果(升级版)
    P1223 排队接水
    【深基12.例1】部分背包问题
    全排列和组合
    P1036 选数
    100——第25例
    100——第24例
    100——第23例
  • 原文地址:https://www.cnblogs.com/00isok/p/8871057.html
Copyright © 2011-2022 走看看