poj 3080 KMP+暴力

来源:互联网 发布:tbc数据库 编辑:程序博客网 时间:2024/05/17 08:04
题意:求给出字符串的公共子序列。。
思路:把第一个字符串的子序列作为KMP的模式串,依次和其它的字符串匹配,求出长度最长的,如果长度相同的话,取字典序较小的。
#include<iostream>using namespace std;int next[65];char str[65];char ans[65];char s[15][65];int h;void get_next(char *T,int len)//求长度为len,串T的next数组{  int j=0,k=-1;  next[0]=-1;  while(j<len)  {    if(k==-1||T[j]==T[k])    {      next[j+1]=k+1;      j++;k++;    }    else    k=next[k];  }  //for(int i=0;i<len;i++)  //printf("%d ",next[i]);}bool find(char *str)//KMP匹配函数{  int len=strlen(str);    int i=0,j=0;    while(i<=60&&j<len)    {      if(j==-1||s[h][i]==str[j])      {        j++;i++;      }      else      j=next[j];    }    if(j==len) return true;//匹配成功    else  return false;}int main(){  int t,k,l,n;  scanf("%d",&t);  while(t--)  {    scanf("%d",&n);    for(int i=0;i<n;i++)    scanf("%s",s[i]);    int t_len=0;    for(int i=1;i<=60;i++)//暴力枚举字符串的子序列,长度为i    {      for(int j=0;j<=60-i;j++)//j到i+j的字符串        {        for(k=j,l=0;k<i+j;k++,l++)//把模式串存到数组str中        str[l]=s[0][k];        str[l]='\0';//注意这里        get_next(str,i);        //for(int m=0;m<i;m++)        //printf("%d ",next[m]);        //system("pause");        for(h=1;h<n;h++)        if(!find(str))  break;//依次和其它字符串匹配的过程        if(h==n)        {          if(t_len<i)//保证最长          {            t_len=i;            strcpy(ans,str);          }          else if(t_len==i)          {            if(strcmp(ans,str)>0)//保证字典序            {              strcpy(ans,str);            }          }        }        //else        //printf("No\n");      }    }    if(t_len>=3)//长度至少是3    printf("%s\n",ans);    else    printf("no significant commonalities\n");  }}


原创粉丝点击