poj1226 kmp查找多字符串正逆最長子串或stl中string法

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+二分

代碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<algorithm>
#define N 110
using namespace std;
char a[N][N],t1[N],t2[N];
int nex[N];
void nexx(char *a){
    int j=0,k=-1;
    nex[0]=-1;
    int n=strlen(a);
    while(j<n){
        if(k==-1||a[j]==a[k]){
            k++;j++;
            if(a[j]!=a[k])nex[j]=k;
            else nex[j]=nex[k];
        }else k=nex[k];
    }
}
bool kmp(char *a,char *b){
    int i=0,j=0,n,m;
    n=strlen(a);
    m=strlen(b);
    if(n<m)return false;
    nexx(b);
    while(i<n&&j<m){
        if(j==-1||a[i]==b[j]){
            i++;j++;
        }else j=nex[j];
    }
    if(j==m)return true;
    return false;
}
int main(){
    int T,n;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%s",a[i]);
        }
        int m=strlen(a[0]),maxx=0;
        int l=1,r=m;
        while(l<=r){
            int mid=(l+r)>>1;
            bool flag=false;
            for(int i=0;i<=m-mid;i++){
                strncpy(t1,a[0]+i,mid);
                t1[mid]='\0';
                int k=0;
                for(int j=mid-1;j>=0;j--){
                    t2[k++]=t1[j];
                }
                t2[k]='\0';
                for(k=1;k<n;k++){
                    if(!kmp(a[k],t1)&&!kmp(a[k],t2))break;
                }
                if(k==n){
                    maxx=max(maxx,mid);
                    flag=true;break;
                }
            }
            if(flag)l=mid+1;
            else r=mid-1;
        }
        printf("%d\n",maxx);
    }
    return 0;
}

方法二:

可以用C++ STL 裏面的東西 去找子串 
因爲題目要求 是可以逆字符串的 
所以可以用reverse 
然後 查找可以用find

代碼如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
using namespace std;
const int maxn = 1e2 + 5;
const int MOD = 1e9 + 7;
string s[maxn];

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n;
        cin >> n;
        int i, j, k;
        int sub;
        int len = 200;
        for (i = 0; i < n; i++)
        {
            cin >> s[i];
            if (s[i].size() < len)
            {
                len = s[i].size();
                sub = i;
            }
        }
        int ans = 0;
        for (i = s[sub].size(); i > 0; i--)
        {
            for (j = 0; j < s[sub].size() - i + 1; j++)
            {
                string s1, s2;
                s1 = s[sub].substr(j, i);
                s2 = s1;
                reverse(s2.begin(), s2.end());
                for (k = 0; k < n; k++)
                {
                    if (s[k].find(s1, 0) == -1 && s[k].find(s2, 0) == -1)
                        break;
                }
                if (k == n && s1.size() > ans)
                    ans = s1.size();
            }
        }
        cout << ans << endl;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章