Newer
Older
#pragma once
#include <string/CyclicString.h>
namespace string {
namespace simplify {
/**
* Computes lexicographically least circular rotation,
* based on Kellogg S. Booth 1979,
* modified to working code by Ladislav Vagner
*/
* Computes lexicographically least circular rotation,
* based on Kellogg S. Booth 1979,
* modified to working code by Ladislav Vagner
*
* \tparam SymbolType the type of symbols in the rotated string.
*
* \param string the rotated string
*
* \return the @p string in its least lexicographical rotation
template < class SymbolType >
static string::CyclicString < SymbolType > normalize(const string::CyclicString < SymbolType > & string);
template < class SymbolType >
string::CyclicString < SymbolType > NormalizeRotation::normalize(const string::CyclicString < SymbolType > & string) {
const ext::vector < SymbolType > & data = string.getContent ( );
int * f = new int [ 2 * data.size ( ) ]; /** Knuth–Morris–Pratt like array */
size_t k = 0; /** Least circular string shift value */
int i = f [ j - k - 1 ];
while ( i != -1 && data [ j % data.size ( ) ] != data [ ( k + i + 1 ) % data.size ( ) ] ) {
if ( data [ j % data.size ( ) ] < data [ ( k + i + 1 ) % data.size ( ) ] )
k = j - i - 1;
i = f [ i ];
}
if ( i == -1 && data [ j % data.size ( ) ] != data [ k % data.size ( ) ] ) {
if ( data [ j % data.size ( ) ] < data [ ( k + i + 1 ) % data.size ( ) ] )
k = j;
} else {
f [ j - k ] = i + 1;
}
}
delete [] f;
if(k == 0)
return string;
for ( unsigned l = k % data.size ( ); l < data.size() + k % data.size ( ); ++l ) {
rotated.push_back ( data [ l % data.size ( ) ] );
}
return string::CyclicString < SymbolType > { string.getAlphabet ( ), rotated };
} /* namespace simplify */
} /* namespace string */