POJ 1226 Substrings(最长公共连续串的变形,可以倒转+KMP)
2013-08-06 11:11
405 查看
Substrings
Description
You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings.
Input
The first line of the input contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains a single integer n (1 <= n <= 100), the number of given strings, followed
by n lines, each representing one string of minimum length 1 and maximum length 100. There is no extra white space before and after a string.
Output
There should be one line per test case containing the length of the largest string found.
Sample Input
Sample Output
题目大意:给你n个串,求最小公共连续子串,不过这个可以倒转,比如ro和or可以匹配
解题思路:思路很清晰,把第一个串当模式串,分解求next匹配然后逆转求next匹配。自己的思路是先顺序找到子串,然后再找它的逆转串的相对位置。例如模式串abcdefg,我先逆转模式串放在另一个数组里面。子串可以是bcde(sta=1,len=1+4)逆转就变成了edcb(sta=7-1-4,len=7-1).这样把规律看出来就可以了。果断一A!
题目地址:Substrings
AC代码:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 10451 | Accepted: 3598 |
You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings.
Input
The first line of the input contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains a single integer n (1 <= n <= 100), the number of given strings, followed
by n lines, each representing one string of minimum length 1 and maximum length 100. There is no extra white space before and after a string.
Output
There should be one line per test case containing the length of the largest string found.
Sample Input
2 3 ABCD BCDFF BRCD 2 rose orchid
Sample Output
2 2
题目大意:给你n个串,求最小公共连续子串,不过这个可以倒转,比如ro和or可以匹配
解题思路:思路很清晰,把第一个串当模式串,分解求next匹配然后逆转求next匹配。自己的思路是先顺序找到子串,然后再找它的逆转串的相对位置。例如模式串abcdefg,我先逆转模式串放在另一个数组里面。子串可以是bcde(sta=1,len=1+4)逆转就变成了edcb(sta=7-1-4,len=7-1).这样把规律看出来就可以了。果断一A!
题目地址:Substrings
AC代码:
#include<iostream> #include<cstring> #include<string> #include<cstdio> using namespace std; int nextp[105],nexts[105],n; char a[105][105]; char b[105]; //将模式串翻转 int lena0; //模式串的长度 //我的思路是用第一个字符串当模式串,然后再枚举长度由大到小求next匹配 void getnextp(int sta,int len) //模式串 { int i,j; len=sta+len; //相对位置变成绝对位置 nextp[sta]=sta,nextp[sta+1]=sta; for(i=sta+1;i<len;i++) { j=nextp[i]; while(j!=sta&&a[0][i]!=a[0][j]) j=nextp[j]; if(a[0][i]==a[0][j]) nextp[i+1]=j+1; else nextp[i+1]=sta; } } void getnexts(int sta,int len) //翻转后的模式串 { int i,j; sta=lena0-sta-len; //要把子串的位置转换成b的位置 len=sta+len; nexts[sta]=sta,nexts[sta+1]=sta; for(i=sta+1;i<len;i++) { j=nexts[i]; while(j!=sta&&b[i]!=b[j]) j=nexts[j]; if(b[i]==b[j]) nexts[i+1]=j+1; else nexts[i+1]=sta; } } int KMP(int sta,int len) { int i,j,k; int sta1=sta; int sta2=lena0-sta-len; int len1=sta+len; int len2=sta2+len; for(k=1;k<n;k++) //后面的串都和第一个串的子串匹配 { int flag=0; j=sta1; for(i=0;i<strlen(a[k]);i++) { while(j!=sta1&&a[k][i]!=a[0][j]) j=nextp[j]; if(a[k][i]==a[0][j]) j++; if(j==len1) { flag=1; break; } } j=sta2; for(i=0;i<strlen(a[k]);i++) { while(j!=sta2&&a[k][i]!=b[j]) j=nexts[j]; if(a[k][i]==b[j]) j++; if(j==len2) { flag=1; break; } } if(flag==0) //有一个没有匹配,便返回0 return 0; } return 1; } int main() { int i,j,T,l; scanf("%d",&T); while(T--) { scanf("%d",&n); if(n==0) break; for(i=0;i<n;i++) scanf("%s",a[i]); lena0=strlen(a[0]); for(i=0;i<lena0;i++) b[i]=a[0][lena0-i-1]; b[lena0]='\0'; int flag=0; for(i=lena0;i>=1;i--) //从长度lena0开始往下枚举 { int flag1=0; //长度为i的是否存在 for(j=0;j<=lena0-i;j++) //模式串分解的起始位置 { getnextp(j,i); getnexts(j,i); if(KMP(j,i)) { flag1=1; printf("%d\n",i); break; } } if(flag1) { flag=1; break; } } if(flag==0) puts("0"); } return 0; }
相关文章推荐
- poj 1226 Substrings 求n个字符串的最长公共子串(这里可以是反序相同) 后缀数组
- poj 1226 hdu 1238 Substrings 求若干字符串正串及反串的最长公共子串 2002亚洲赛天津预选题
- poj 1226 求多串最长公共子串 或 回文子串 KMP&&strstr&&后缀数组
- POJ 1226 Substrings (后缀数组 n个串的最长公共子串)
- poj 3080 Blue Jeans (KMP+最长公共子串)
- HDU1238 Substrings(kmp,最长公共子串)
- POJ 1226 Substrings(KMP+枚举)
- poj 1226 出现或反转后出现在每个字符串中的最长子串(后缀数组/kmp)
- poj1226——Substrings//KMP
- 【KMP多串最长公共子串】POJ 3080
- poj 1226|| hdu 1238 Substrings(KMP)
- POJ 3450 Corporate Identity(KMP:最长连续公共子序列)
- poj 1226 Substrings (string||KMP)
- POJ 1226(最长公共子串含逆序)
- 【KMP求多个串的最长公共子串】POJ 3450
- poj 3080 kmp求解多个字符串的最长公共字串,(数据小,有点小暴力 16ms)
- POJ 1226 Substrings KMP暴力 或 后缀数组
- POJ 1226 && HDU 1238 Substrings(kmp)
- POJ 3080 Blue Jeans(KMP 最长公共子串)
- poj 1226 Substrings(二分 + kmp)