程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 3080 Blue Jeans (KMP)

POJ 3080 Blue Jeans (KMP)

編輯:C++入門知識

求出公共子序列  要求最長  字典序最小

枚舉第一串的所有子串   然後對每一個串做KMP。找到目標子串

學會了   strncpy函數的使用   我已可入靈魂  

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

char str[20][70];
char tmp[70],ans[70];
int f[70];
int n;

void getfail(char *P)
{
    int m=strlen(P);
    f[0]=0;f[1]=0;
    for(int i=1;i<m;i++)
    {
        int j=f[i];
        while(j&&P[i]!=P[j])j=f[j];
        f[i+1]=P[i]==P[j]?j+1:0;
    }
}

bool find(char *P,char *T)
{
    int n=strlen(T);
    int m=strlen(P);
    getfail(P);
    int j=0;
    for(int i=0;i<n;i++)
    {
        while(j&&P[j]!=T[i])j=f[j];
        if(P[j]==T[i])j++;
        if(j==m)return true;//printf("%d\n",i-m+1);
    }
    return false;
}

bool work(char *tmp,int l)//l : tmp   len: ans
{
    for(int i=2;i<=n;i++)
    {
        if(!find(tmp,str[i]))return false;
    }
    int len=strlen(ans);

    if(l>len)strcpy(ans,tmp);//最長
    else if(l==len && strcmp(tmp,ans)<0)strcpy(ans,tmp);//字典序最小

    return true;
}

int main()
{
    int CASE;
    scanf("%d",&CASE);

    while(CASE--)
    {
        scanf("%d",&n);

        for(int i=1;i<=n;i++)
        scanf("%s",str[i]);

        memset(ans,0,sizeof(ans));

        memset(tmp,0,sizeof(tmp));

        int len=strlen(str[1]);

        for(int i=1;i<=len;i++)
        {
            for(int j=0;j<len-i+1;j++)
            {
                strncpy(tmp,str[1]+j,i);
                work(tmp,i);
            }
        }
        if(strlen(ans)>=3)printf("%s\n",ans);//題目中說要至少3個長度
        else printf("no significant commonalities\n");
    }
    return 0;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved