Substrings kmp

  

Problem Description
You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings.
 

 

Input
The first line of the input file contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains a single integer n (1 <= n <= 100), the number of given strings, followed by n lines, each representing one string of minimum length 1 and maximum length 100. There is no extra white space before and after a string.
 

 

Output
There should be one line per test case containing the length of the largest string found.
 

 

Sample Input
2 3 ABCD BCDFF BRCD 2 rose orchid
 

 

Sample Output
2 2
 
直接暴力kmp便可  
有一個函數 :reverse(p2.begin(),p2.end()); 能夠直接反轉 
注意若是沒有則輸出0;
 
第一次的寫法  雖然艱難的過了 可是時間爲500ms
 
#include<bits/stdc++.h>
using namespace std;
//input
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);i--)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m);
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define inf 0x3f3f3f3f
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define N 100+5
#define mod 10007
string s,p;
int can[105];
string temp[N];
int nex[N];
string str;
int lenp,lens;
void getnext()
{
    nex[0]=-1;
    int k=-1,j=0;
    while(j<lenp-1)
    {
        if(k==-1||p[k]==p[j])
            nex[++j]=++k;
        else k=nex[k];
    }
}
int kmp(string s)
{
  int lens=s.size();
  int j=0,i=0;
  while(i<lens&&j<lenp)
  {
      if(s[i]==p[j]||j==-1)
      {
          i++;
          j++;
      }
      else j=nex[j];
      if(j==lenp)
      {
        return 1;
      }
  }
return 0;
}
int main()
{

    int cas;
    RI(cas);
    while(cas--)
    {
        int n;RI(n);
        int minn=inf;
        rep(i,1,n)
        {
        cin>>temp[i];
        if(temp[i].size()<minn )minn=temp[i].size();
        }
        rep(i,1,n)
        if(temp[i].size()==minn)
        {
            str=temp[i];
            break;
        }
        int end1=0;
        int maxx=0;
        for(lenp=minn;lenp>=1;lenp--)
        {
            if(end1)break;
            for(int j=0;j<=minn;j++)
            if(j+lenp-1<minn)
            {
                int ok=1;
                p=str.substr(j,lenp);
                getnext();
                rep(i,1,n)
                {
                    can[i]=0;

                    if(kmp(temp[i]))
                        can[i]=1;
                }
                reverse(p.begin(),p.end());
                getnext();
                rep(i,1,n)
                {

                    if(kmp(temp[i]))
                        can[i]=1;

                    if(can[i]==0)
                    {
                        ok=0;break;
                    }
                }
                if(ok)
                {
                    maxx=lenp;end1=1;
                    break;
                }
            }
        }
        cout<<maxx<<endl;
    }
    return 0;
}
View Code

 

 
下面的爲70ms
 由於其實大部分狀況下是不匹配的  匹配的狀況微乎其微   因此直接兩個一塊兒判斷便可  即便每次判斷都要更行next
 
#include<bits/stdc++.h>
using namespace std;
//input
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);i--)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m);
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define inf 0x3f3f3f3f
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define N 100+5
#define mod 10007
string s,p;
int can[105];
string temp[N];
int nex[N];
string str;
int lenp,lens;
void getnext()
{
    nex[0]=-1;
    int k=-1,j=0;
    while(j<lenp-1)
    {
        if(k==-1||p[k]==p[j])
            nex[++j]=++k;
        else k=nex[k];
    }
}
int kmp(string s)
{
  int lens=s.size();
  int j=0,i=0;
  while(i<lens&&j<lenp)
  {
      if(s[i]==p[j]||j==-1)
      {
          i++;
          j++;
      }
      else j=nex[j];
      if(j==lenp)
      {
        return 1;
      }
  }
return 0;
}
int main()
{
    int cas;
    RI(cas);
    while(cas--)
    {
        int n;RI(n);
        int minn=inf;
        rep(i,1,n)
        {
        cin>>temp[i];
        if(temp[i].size()<minn )minn=temp[i].size();
        }
        rep(i,1,n)
        if(temp[i].size()==minn)
        {
            str=temp[i];
            break;
        }
        int maxx=0;
        int end1=0;
        for(lenp=minn;lenp>=1;lenp--)
        {
            if(end1)break;
            for(int j=0;j<=minn;j++)
            if(j+lenp-1<minn)
            {
                string p1=str.substr(j,lenp);
                string p2=p1;
                reverse(p2.begin(),p2.end());

                int i;
                for(i=1;i<=n;i++)
                {
                    int flag=0;
                    p=p1;
                    getnext();
                    if(kmp(temp[i]))
                        flag=1;
                    p=p2;
                    getnext();
                    if(kmp(temp[i]))
                        flag=1;
                    if(flag==0)
                    break;
                }
                if(i==n+1&&maxx<lenp)
                    maxx=lenp,end1=1;
            }
        }
        cout<<maxx<<endl;
    }
    return 0;
}
View Code
相關文章
相關標籤/搜索