Returns the length of the longest common substring of two strings using a suffix array.
For more information, see Luo Sui's paper.
[Cpp]
# Include <iostream>
# Include <cstdio>
# Include <cstring>
# Include <string>
# Include <algorithm>
# Include <cstdlib>
# Define maxn1000005
Using namespace std;
Int r [MAXN];
Int wa [MAXN], wb [MAXN], wv [MAXN], tmp [MAXN];
Int sa [MAXN]; // index range 1 ~ N value range 0 ~ N-1
Int cmp (int * r, int a, int B, int l)
{
Return r [a] = r [B] & r [a + l] = r [B + l];
}
Void da (int * r, int * sa, int n, int m)
{
Int I, j, p, * x = wa, * y = wb, * ws = tmp;
For (I = 0; I <m; I ++) ws [I] = 0;
For (I = 0; I <n; I ++) ws [x [I] = r [I] ++;
For (I = 1; I <m; I ++) ws [I] + = ws [I-1];
For (I = n-1; I> = 0; I --) sa [-- ws [x [I] = I;
For (j = 1, p = 1; p <n; j * = 2, m = p)
{
For (p = 0, I = n-j; I <n; I ++) y [p ++] = I;
For (I = 0; I <n; I ++)
If (sa [I]> = j) y [p ++] = sa [I]-j;
For (I = 0; I <n; I ++) wv [I] = x [y [I];
For (I = 0; I <m; I ++) ws [I] = 0;
For (I = 0; I <n; I ++) ws [wv [I] ++;
For (I = 1; I <m; I ++) ws [I] + = ws [I-1];
For (I = n-1; I> = 0; I --) sa [-- ws [wv [I] = y [I];
For (swap (x, y), p = 1, x [sa [0] = 0, I = 1; I <n; I ++)
X [sa [I] = cmp (y, sa [I-1], sa [I], j )? P-1: p ++;
}
}
Int rank [MAXN]; // index range 0 ~ N-1 value range 1 ~ N
Int height [MAXN]; // index from 1 (height [1] = 0)
Void calheight (int * r, int * sa, int n)
{
Int I, j, k = 0;
For (I = 1; I <= n; ++ I) rank [sa [I] = I;
For (I = 0; I <n; height [rank [I ++] = k)
For (k? K --: 0, j = sa [rank [I]-1]; r [I + k] = r [j + k]; ++ k );
Return;
}
Char s1 [MAXN], s2 [MAXN];
Int main ()
{
While (scanf ("% s", s1, s2 )! = EOF)
{
Int len = strlen (s1 );
Strcat (s1, "$ ");
Strcat (s1, s2 );
Int n = strlen (s1), m = 0;
For (int I = 0; I <n; I ++)
{
M = max (m, (int) s1 [I]);
R [I] = s1 [I];
}
R [n] = 0;
Da (r, sa, n + 1, m + 1); // note that n + 1 is the cause.
Calheight (r, sa, n );
Int res = 0;
For (int I = 1; I <n; I ++)
If (sa [I-1] <len & sa [I]> = len) | (sa [I-1]> = len & sa [I] <len) res = max (res, height [I]);
Printf ("% d \ n", res );
}
Return 0;
}
# Include <iostream>
# Include <cstdio>
# Include <cstring>
# Include <string>
# Include <algorithm>
# Include <cstdlib>
# Define maxn1000005
Using namespace std;
Int r [MAXN];
Int wa [MAXN], wb [MAXN], wv [MAXN], tmp [MAXN];
Int sa [MAXN]; // index range 1 ~ N value range 0 ~ N-1
Int cmp (int * r, int a, int B, int l)
{
Return r [a] = r [B] & r [a + l] = r [B + l];
}
Void da (int * r, int * sa, int n, int m)
{
Int I, j, p, * x = wa, * y = wb, * ws = tmp;
For (I = 0; I <m; I ++) ws [I] = 0;
For (I = 0; I <n; I ++) ws [x [I] = r [I] ++;
For (I = 1; I <m; I ++) ws [I] + = ws [I-1];
For (I = n-1; I> = 0; I --) sa [-- ws [x [I] = I;
For (j = 1, p = 1; p <n; j * = 2, m = p)
{
For (p = 0, I = n-j; I <n; I ++) y [p ++] = I;
For (I = 0; I <n; I ++)
If (sa [I]> = j) y [p ++] = sa [I]-j;
For (I = 0; I <n; I ++) wv [I] = x [y [I];
For (I = 0; I <m; I ++) ws [I] = 0;
For (I = 0; I <n; I ++) ws [wv [I] ++;
For (I = 1; I <m; I ++) ws [I] + = ws [I-1];
For (I = n-1; I> = 0; I --) sa [-- ws [wv [I] = y [I];
For (swap (x, y), p = 1, x [sa [0] = 0, I = 1; I <n; I ++)
X [sa [I] = cmp (y, sa [I-1], sa [I], j )? P-1: p ++;
}
}
Int rank [MAXN]; // index range 0 ~ N-1 value range 1 ~ N
Int height [MAXN]; // index from 1 (height [1] = 0)
Void calheight (int * r, int * sa, int n)
{
Int I, j, k = 0;
For (I = 1; I <= n; ++ I) rank [sa [I] = I;
For (I = 0; I <n; height [rank [I ++] = k)
For (k? K --: 0, j = sa [rank [I]-1]; r [I + k] = r [j + k]; ++ k );
Return;
}
Char s1 [MAXN], s2 [MAXN];
Int main ()
{
While (scanf ("% s", s1, s2 )! = EOF)
{
Int len = strlen (s1 );
Strcat (s1, "$ ");
Strcat (s1, s2 );
Int n = strlen (s1), m = 0;
For (int I = 0; I <n; I ++)
{
M = max (m, (int) s1 [I]);
R [I] = s1 [I];
}
R [n] = 0;
Da (r, sa, n + 1, m + 1); // note that n + 1 is the cause.
Calheight (r, sa, n );
Int res = 0;
For (int I = 1; I <n; I ++)
If (sa [I-1] <len & sa [I]> = len) | (sa [I-1]> = len & sa [I] <len) res = max (res, height [I]);
Printf ("% d \ n", res );
}
Return 0;
}