Blue Jeans POJ - 3080 (多個字串的最長公共子串)
阿新 • • 發佈:2018-11-06
題意:
給定n個字串,要你求出這n個字串的最長公共子串,如果存在多個輸出字典序最小的那個.
分析:
KMP+暴力去列舉即可.
#include<stdio.h> #include<string.h> const int maxn = 107; const int oo = 1e9+7; char s[maxn][maxn]; int f[maxn]; void getFail(char *P) { int m = strlen(P); f[0] = f[1] = 0; for(int i = 1; i < m; i++)//雖然字串是0到m-1,但是要求出f[m]的值 { 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 *T, char *P) //找到所有匹配點 { int n = strlen(T); int m = strlen(P); int j = 0; for(int i = 0; i < n; i++) { while(j && T[i] != P[j]) j = f[j]; if(T[i] == P[j]) j++; if(j == m) return true;//就算j到m了,也用f[m]繼續匹配 } return false; } int main() { int T; scanf("%d", &T); while(T--) { int i, j, len, M, MaxLen=60; char ans[maxn] = "Z"; scanf("%d", &M); for(i=0; i<M; i++) scanf("%s", s[i]); for(len=60; len>=3; len--) for(i=0; i<=MaxLen-len; i++) {///列舉第一個串的所有子串 char b[maxn]={0}; strncpy(b, s[0]+i, len); getFail(b); for(j=1; j<M; j++) { if(find(s[j], b) == false) break; } if(j==M && strcmp(ans, b) > 0) strcpy(ans, b); if(ans[0] != 'Z' && i==MaxLen-len) i=100, len = 0;///跳出迴圈 } if(ans[0] == 'Z') printf("no significant commonalities\n"); else printf("%s\n", ans); } return 0; }