给你一堆字符串,编号从1到n,要求输出它上面所有字符串不全是它子串的最大位置,如果没有输出-1
主要就是KMP,每次在上面找到一个不匹配的子串就把位置记录下来,匹配时只匹配记录位置的子串和它前一个子串,如果记录位置的子串再后来被匹配成功了就消除这个位置。
样例
4
5
ab
abc
zabc
abcd
zabcd
4
you
lovinyou
aboutlovinyou
allaboutlovinyou
5
de
def
abcd
abcde
abcdef
3
a
bc
ccc
输出
Case #1: 4
Case #2: -1
Case #3: 4
Case #4:3
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int _next[2100];
char s[505][2100];
int lena,lenb;
int num[505],l;
void getnext(int tt)
{
int i=0,j=-1;
_next[0]=-1;
while(i<lenb)
{
if(j==-1||s[tt][i]==s[tt][j])
_next[++i]=++j;
else
j=_next[j];
}
}
int main()
{
int T;
scanf("%d",&T);
for(int k=1;k<=T;k++)
{
int n;
scanf("%d",&n);
int ok=-1;//ok means the final answer
bool flag=false;//判断是否输出-1
l=0;//l代表不匹配的字符串数
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
num[l+1]=i-1;//num储存不匹配的字符串的位置,num[]==-1时代表原来不匹配的在后来可以匹配了
if(i>1)
for(int ka=1;ka<=l+1;ka++)//不知道为什么当时写的KMP函数一直调用不了,遂直接写到主函数里
{
int j=num[ka];
if(j==-1) continue;
memset(_next,0,sizeof(_next));
lena=strlen(s[i]);
lenb=strlen(s[j]);
int ans;
int tb=j,ta=i;
int ti=0,tj=0;
getnext(tb);
while(ti<lena&&tj<lenb)
{
if(tj==-1||s[ta][ti]==s[tb][tj])
{
ti++;
tj++;
}
else
tj=_next[tj];
}
if(tj<lenb&&ti==lena)
{
ans=-1;
flag=true;//有一个不匹配就不会输出-1
num[++l]=i-1;
ok=i+1;
break;
}
else
{
ans=1;
num[ka]=-1;
}
}
}
printf("Case #%d: ",k);
if(flag==false)
printf("-1\n");
else printf("%d\n",ok);
}
}