typedef long long lld;
const int INF = 1000000000;
const int MAX = 1000005;
int a[MAX];
int b[MAX];
char S[MAX], T[MAX];
//a[i] 为T与T(i,n)的最长公共前缀长度
//b[i] 为T与S(i,n)的最长公共前缀长度
void get_fail(char *S, char *T, int n, int m)
{
int i, j = 0;
a[0] = m; //第一个公共前缀长度必然为m
while (1 + j < m && T[j] == T[1 + j])
j++;
a[1] = j;
int k = 1; //k上一次计算的起始位置
int need = 0;
for (i = 2; i < m; i++)
{
need = k + a[k] - i; //判断是否需要计算
//cout << "i: " << i << " k:" <<k << " need: " << need << endl;
if (a[i - k] < need)
a[i] = a[i - k];
else
{
j = 0 > need ? 0 : need;
while (i + j < m && T[j] == T[j + i])
j++;
a[i] = j; //计算的j 为公共前缀的长度
k = i;
}
}
j = 0;
while (j < n && j < m && S[j] == T[j])
j++;
b[0] = j;
k = 0;
for (i = 1; i < n; i++)
{
need = k + b[k] - i;//k记录前面的最大位置
//cout << "i: " << i << " k:" <<k << " need: " << need << endl;
if (a[i - k] < need)
b[i] = a[i - k];
else
{
j = 0 > need ? 0 : need;
while (i + j < n && j < m && S[i + j] == T[j])
j++;
b[i] = j;
k = i;
}
}
}
//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
int main()
{
int n, m;
int last = 0;
int i, j, k;
freopen("in.txt", "r", stdin);
while (scanf("%s%s", &S, &T) != EOF)
{
n = strlen(S);
m = strlen(T);
get_fail(S, T, n, m);
// for(int i=0; i<=10; i++)
// cout << a[i] << " ";
// cout << endl;
// for(int i=0; i<=10; i++)
// cout << b[i] << " ";
// cout << endl;
int ans = 0;
for (i = 0; i < n; i++)
{
if (b[i] == n - i)
{
ans = b[i];
break;
}
}
printf("%d\n", ans);
}
return 0;
}
测试数据:
abcde cdefg
abcdab dacdacg