pku3450 Corporate Identity &&pku3080 Blue Jeans(枚举+KMP)

题意:求多个串的最长公共子串

pku3450用KMP算法

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int nxt[210];
char str[4010][210],s[210];
int n,m;
bool KMP(char *T,char *P)
{
	memset(nxt,0,sizeof(nxt));
	nxt[0]=-1;
	int k=-1;
	for(int q=1;q<m;q++)
	{
		while(k>-1&& P[k+1]!=P[q])
			k=nxt[k];
		if(P[k+1]==P[q])
			k++;
		nxt[q]=k;
	}
	int j=-1,i=0;
	while(T[i])
	{
		while(j>-1 && P[j+1]!=T[i])
			j=nxt[j];
		if(P[j+1]==T[i])
			j++;
		if(j+1==m)
			return true;
		i++;
	}
	return false;
}
int main()
{
	int t;
	while(scanf("%d",&t)==1 && t)
	{
	   int l,min1=10000;
       for(int i=0;i<t;i++)  
        {  
            scanf("%s",str[i]);  
            if(strlen(str[i])<min1)  
            {  
              min1=strlen(str[i]);  
              l=i;  
            }  
        }  
        char os[210],ans=0;  
        for(int i=0;i<strlen(str[l]);i++)  
        {  
            for(int j=i;j<strlen(str[l]);j++)//变量i和j 用来枚举字串的首和尾  
            {  
                int b=0;  
                for(int k=i;k<=j;k++)//枚举最短字串的长度,正串和反串  
                    os[b++]=str[l][k];   
                os[b]='\0'; 
				m=b;
                int flag=1;  
                for(int k=0;k<t;k++)  
                {  
                    if(!KMP(str[k],os))  
                       {  
                            flag=0;break;  
                       }  
                }  
                   if(flag&&ans<strlen(os))  
				   {
					    strcpy(s,os);
                        ans=strlen(os);  
				   }
				   else if(flag && ans==strlen(os))
				   {
					    if(strcmp(s,os)==1)
							strcpy(s,os);
				   }
            }  
        }  
		if(ans>0)
        printf("%s\n",s); 
		else puts("IDENTITY LOST");
    }  
	return 0;
}


 pku3450用strstr()函数

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
char str[4010][210],s[210];
int n,m;
int main()
{
	int t;
	while(scanf("%d",&t)==1 && t)
	{
	   int l,min1=10000;
       for(int i=0;i<t;i++)  
        {  
            scanf("%s",str[i]);  
            if(strlen(str[i])<min1)  
            {  
              min1=strlen(str[i]);  
              l=i;  
            }  
        }  
        char os[210],ans=0;  
        for(int i=0;i<strlen(str[l]);i++)  
        {  
            for(int j=i;j<strlen(str[l]);j++)//变量i和j 用来枚举字串的首和尾  
            {  
                int b=0;  
                for(int k=i;k<=j;k++)//枚举最短字串的长度,正串和反串  
                    os[b++]=str[l][k];   
                os[b]='\0'; 
                int flag=1;  
                for(int k=0;k<t;k++)  
                {  
                    if(!strstr(str[k],os))//正串和反串都没有在字符串在出现  
                       {  
                            flag=0;break;  
                       }  
                }  
                   if(flag&&ans<strlen(os))  
				   {
					    strcpy(s,os);
                        ans=strlen(os);  
				   }
				   else if(flag && ans==strlen(os))
				   {
					    if(strcmp(s,os)==1)
							strcpy(s,os);
				   }
            }  
        }  
		if(ans>0)
        printf("%s\n",s); 
		else puts("IDENTITY LOST");
    }  
	return 0;
}

 pku3080

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int nxt[100];
char str[15][110],s[110];
int n,m;
bool KMP(char *T,char *P)
{
	memset(nxt,0,sizeof(nxt));
	nxt[0]=-1;
	int k=-1;
	for(int q=1;q<m;q++)
	{
		while(k>-1&& P[k+1]!=P[q])
			k=nxt[k];
		if(P[k+1]==P[q])
			k++;
		nxt[q]=k;
	}
	int j=-1,i=0;
	while(T[i])
	{
		while(j>-1 && P[j+1]!=T[i])
			j=nxt[j];
		if(P[j+1]==T[i])
			j++;
		if(j+1==m)
			return true;
		i++;
	}
	return false;
}
int main()
{
	int cas,t;
	scanf("%d",&cas);
	while(cas--)
	{
		scanf("%d",&n);
	   int l,min1=10000;
       for(int i=0;i<n;i++)  
        {  
            scanf("%s",str[i]);  
            if(strlen(str[i])<min1)  
            {  
              min1=strlen(str[i]);  
              l=i;  
            }  
        }  
        char os[210],ans=0;  
        for(int i=0;i<strlen(str[l]);i++)  
        {  
            for(int j=i;j<strlen(str[l]);j++)//变量i和j 用来枚举字串的首和尾  
            {  
                int b=0;  
                for(int k=i;k<=j;k++)//枚举最短字串的长度,正串和反串  
                    os[b++]=str[l][k];   
                os[b]='\0'; 
				m=b;
                int flag=1;  
                for(int k=0;k<n;k++)  
                {  
                    if(!KMP(str[k],os))  
                       {  
                            flag=0;break;  
                       }  
                }  
                   if(flag&&ans<strlen(os))  
				   {
					    strcpy(s,os);
                        ans=strlen(os);  
				   }
				   else if(flag && ans==strlen(os))
				   {
					    if(strcmp(s,os)==1)
							strcpy(s,os);
				   }
            }  
        }  
		if(ans>=3)
        printf("%s\n",s); 
		else puts("no significant commonalities");
    }  
	return 0;
}


原文地址:https://www.cnblogs.com/nanke/p/2243466.html