• dutacm.club_1087_Common Substrings_(KMP)_(结合此题通俗理解kmp的next数组)


    1087: Common Substrings

    Time Limit:3000/1000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)
    Total Submissions:849   Accepted:108
    [Submit][Status][Discuss]

    Description

    You are given two long strings and B. They are comprised of lowercase letters. You should compute how many suffixes of A are the prefixes of B.

    Input

    In the first line is a number T (0<T100) , indicating the cases following.
    In the next T lines each line contains two strings — A and B.
    0<|A|10^5,0<|B|10^5)

    Output

    There should be exactly T lines.
    Each line contain a number — the answer.

    Sample Input

    1
    abcc ccba

    Sample Output

    2

    HINT

    In the first case, cc and c are two of the suffixes of string A, and they are the prefixes of string B.
     
    题意:给两个字符串A和B,问A的所有后缀中,有多少个是B的前缀。
    一看也是没思路啊。。。题解用的KMP,让我有点懵逼,仔细一想,让我更加理解之前学的kmp。
     
    思路:利用kmp算法中求的next数组的过程即可得到答案,因为next的数组实质是:next[i]表示str[1--i]这个子串的前缀和后缀的最大公共长度(这里的前缀和后缀是之前看的kmp的博文中的定义,与普通的有细微差异)。
    kmp算法利用这个数组,在失配时可以更加快地往后搜索(而不是从字符串的下一个字符开始重新与模式串的第一个字符开始匹配),next[i]的值即为模式串的第i+1个字符失配时将模式串向右移动至next[i]为当前要匹配的字符。因为模式串mo[i-next[i]+1,i](这是个后缀)这个子串与mo[1,next[i]](这是一个前缀)这个子串是一样的,所以将模式串右移至这个前缀代替这个后缀的位置,这样就达到了更加高效匹配的目的。结合博文看容易理解。。。
     
    好题啊好题!!!!!!
     
    #include <cstdio>
    #include <cstring>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<cmath>
    using namespace std;
    #define N 100005
    #define LL long long
    
    char A[N],B[N],T[N<<1];
    int Next[N<<1],lena,lenb,lent;
    
    void getNext()
    {
        int p=0;
        memset(Next,0,sizeof(Next));
        for(int i=2;i<lent;i++)
        {
            while(p>0&&T[p+1]!=T[i])
                p=Next[p];
            if(T[p+1]==T[i])
                p++;
            Next[i]=p;
        }
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%s%s",A,B);
            lena=strlen(A);
            lenb=strlen(B);
            strcpy(T+1,B);
            T[lenb+1]='#';
            strcpy(T+lenb+2,A);
            T[lena+lenb+2]='';
            //cout<<T+1<<endl;
            lent=lena+lenb+2;
            getNext();
            //for(int i=1;i<lent;i++)
             //   cout<<Next[i]<<' ';
            //cout<<endl;
            int tmp=lent-1,res=0;
            while(tmp!=0)
            {
                if(Next[tmp]>0)
                    res++;
                tmp=Next[tmp];
            }
            printf("%d
    ",res);
        }
        return 0;
    }
  • 相关阅读:
    js保留两位小数
    js字符串转成数字的三种方法
    『MySQL』索引类型 normal, unique, full text
    checkstyle配置文件说明
    如何更好地利用Pmd、Findbugs和CheckStyle分析结果
    Hibernate SQL优化技巧dynamic-insert="true" dynamic-update="true"
    Struts2 action的单例与多例
    Eclipse插件checkstyle安装使用
    html 动态显示元素文本
    脱离 Spring 实现复杂嵌套事务,之一(必要的概念)
  • 原文地址:https://www.cnblogs.com/jasonlixuetao/p/6545083.html
Copyright © 2020-2023  润新知