• 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;
    }
  • 相关阅读:
    Oracle之数据库的增删改查和格式的修改
    Oracle之表的相关操作
    Oracle之现有表上建新表、操作符、字符函数
    Oracle之用户和表空间
    相关Linux命令
    克隆环境
    机器学习笔记(四)神经网络的基本概念
    机器学习作业(二)逻辑回归——Python(numpy)实现
    机器学习作业(二)逻辑回归——Matlab实现
    机器学习笔记(三)逻辑回归
  • 原文地址:https://www.cnblogs.com/jasonlixuetao/p/6545083.html
Copyright © 2020-2023  润新知