您的位置:首页 > 其它

【扩展KMP】POJ_3450| HDU_2328 Corporate Identity

2014-07-25 17:19 295 查看
原题直通车:POJ_3450 Corporate Identity HDU_2328
Corporate Identity


题意概述:找出N个串中最长公共子串

分析:

一、可以直接枚举其中一个串的所有字串,跟所有串进行匹配找到结果。

二、用其中一个串的每一个后缀和其它所有串分别求一次扩展KMP,并找到后缀中能在所有串中匹配到的最长前缀,最后在每个后缀的最长前缀中找出最长且字典序最小的。

代码参考:

KMP:

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
using namespace std;
const int maxn=4444;

char x[222],ans[222], f[maxn][222];
int next[222], n;

void strcpy(char *y,int i,int len){
for(int j=0;j<len;++i,++j) x[j]=y[i];
x[len]='\0';
}
void Get_Next(char *s){
int len=strlen(s), i = 0, j = -1;
next[0]=-1;
while(i<len){
if(j==-1||s[i]==s[j]){
if(s[++i]==s[++j]) next[i]=next[j];
else next[i]=j;
}
else j=next[j];
}
}
bool KMP(char *s,char *a){
int ls=strlen(s), la=strlen(a);
Get_Next(a);
int i=0, j=0;
while(i<ls&&j<la){
if(j==-1||s[i]==a[j])
++i,++j;
else j=next[j];
}
if(j==la) return true;
return false;
}
int main(){
while(~scanf("%d",&n),n){
for(int i=0; i<n; ++i) scanf("%s",f[i]);
int len = strlen(f[0]);
bool flag = false;
ans[0]='\0';
for(int i=len; i && !flag; --i)
for(int j=0,k; j<=len-i; ++j) {
strcpy(f[0], j, i);
for(k=1; k<n; ++k) if( !KMP(f[k],x) ) break;
if(k==n && (!flag || strcmp(ans,x)>0)) {
strcpy(ans, x);
flag=true;
}
}
if(flag) puts(ans);
else puts("IDENTITY LOST");
}
return 0;
}


扩展KMP:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[4005][205], f[4005][205], ans[205];
int next[205], extend[205];
void get_next(char *g) {
int lg = strlen(g), j = 0;
next[0] = lg;
while(j+1<lg && g[j] == g[j+1]) ++j;
next[1] = j;
for(int i=2, k=1; i<lg; ++i) {
int p = k+next[k]-1;
int l = next[i-k];
if(i+l < p+1) next[i] = l;
else {
j = (p-i+1>0 ? p-i+1 : 0);
while(i+j<lg && g[j] == g[i+j]) ++j;
next[i] = j;
k = i;
}
}
}
int ExKMP(char *s, char *g) {
int ls = strlen(s), lg = strlen(g), j = 0, max_len;
while(j<lg && j<ls && s[j] == g[j]) ++j;
max_len = extend[0] = j;
for(int i=1, k=0; i<ls; ++i) {
int p = k+extend[k]-1;
int l = next[i-k];
if(i+l < p+1) extend[i] = l;
else {
j = (p-i+1>0 ? p-i+1 : 0);
while(i+j<ls && j<lg && s[i+j] == g[j]) ++j;
extend[i] = j;
k = i;
}
if(extend[i] > max_len) max_len = extend[i];
}
return max_len;
}
int main() {
int n;
while(~scanf("%d", &n) && n) {
for(int i=0; i<n; ++i) scanf("%s", s[i]);
int len = strlen(s[0]), max_len = -1;
for(int i=0; i<len; ++i) {
get_next(s[0]+i);
int mx = -1;
for(int j=1; j<n; ++j) {
int ml = ExKMP(s[j], s[0]+i);
if(mx == -1 || ml < mx) mx = ml;
}
if(mx > max_len || (mx == max_len&&strncmp(ans, s[0]+i, mx)>0)) {
strncpy(ans, s[0]+i, mx);
max_len = mx;
ans[mx] = '\0';
}
}
if(max_len>0) puts(ans);
else puts("IDENTITY LOST");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: