Pagini recente » Cod sursa (job #2331528) | Cod sursa (job #1781335) | Cod sursa (job #178531) | Cod sursa (job #2059648) | Cod sursa (job #189958)
Cod sursa(job #189958)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define FIN "substr.in"
#define FOUT "substr.out"
#define MAX( a, b ) (a) > (b) ? (a) : (b)
#define MIN( a, b ) (a) < (b) ? (a) : (b)
#define NMAX 16385
#define LOGMAX 15
typedef struct nod
{
int first, last;
} NOD;
char S[NMAX];
int SIGMA[255], SUFF[LOGMAX][NMAX], CNT[NMAX], IND[NMAX], TMP[NMAX], ORDER[NMAX] ;
NOD V[NMAX];
int N, K, max_step;
void Norm()
{
int i;
memset( SIGMA, 0, sizeof(SIGMA));
for( i = 0; i < N; i++ )
SIGMA[S[i]] = 1;
for( i = 1; i < 255; i++ )
SIGMA[i] = SIGMA[i-1] + SIGMA[i];
}
void count_sort()
{
int i;
memset( CNT, 0, sizeof(CNT) );
for( i = 1; i <= N; i++ )
CNT[V[i].last]++;
for( i = 1; i <= N; i++ )
CNT[i] += CNT[i-1];
for( i = 1; i <= N; i++ )
{
TMP[CNT[V[i].last]] = i;
CNT[V[i].last]--;
}
memset( CNT, 0, sizeof(CNT));
for( i = 1; i <= N; i++ )
CNT[V[i].first]++;
for( i = 1; i <= N; i++)
CNT[i] += CNT[i-1];
for( i = N; i > 0; i-- )
{
IND[CNT[V[TMP[i]].first]] = TMP[i];
CNT[V[TMP[i]].first]--;
}
}
void build_suffix()
{
int i, step, nr;
// initializez primul nivel
for( i = 1; i <= N; i++ )
SUFF[0][i] = SIGMA[S[i-1]];
bool ord = false;
step = 0;
while( !ord )
{
for( i = 1; i <= N; i++ )
{
V[i].first = SUFF[step][i];
if( i + ( 1 << step ) <= N )
V[i].last = SUFF[step][i + ( 1 << step )];
else
V[i].last = 0;
}
count_sort();
nr = 1; step++;
SUFF[step][IND[1]] = nr;
for( i = 2; i <= N; i++ )
{
if( V[IND[i]].first != V[IND[i-1]].first || V[IND[i]].last != V[IND[i-1]].last )
nr++;
SUFF[step][IND[i]] = nr;
}
if( nr == N ) ord = true;
}
max_step = step;
for( i = 1; i <= N; i++ )
ORDER[SUFF[step][i] ] = i;
}
int lcp( int i, int j )
{
int k = 0, step = max_step;
if( i == j ) return N - i + 1;
while( i <= N && j <= N && step >= 0 )
{
if( SUFF[step][i] == SUFF[step][j] )
{
k += 1 << step;
i += 1 << step;
j += 1 << step;
}
step--;
}
return k;
}
int solve()
{
int max = 0, i;
for( i = K; i <= N; i++ )
max = MAX( max, lcp( ORDER[i - K + 1], ORDER[i] ));
return max;
}
int main()
{
FILE * fin = fopen( FIN, "r" );
FILE * fout = fopen( FOUT, "w" );
fscanf( fin, "%d%d\n", &N, &K );
fscanf( fin, "%s", S );
Norm();
build_suffix();
solve();
fprintf( fout, "%d\n", solve() );
fclose( fin );
fclose( fout );
}