Newer
Older
/*
* NormalizeRotation.h
*
* Created on: 9. 2. 2014
* Author: Jan Travnicek
*/
#ifndef _NORMALIZE_ROTATION_H__
#define _NORMALIZE_ROTATION_H__
#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 */
int k = 0; /** Least circular string shift value */
f [ 0 ] = -1;
for ( unsigned j = 1; j < 2 * data.size ( ); ++j ) {
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;
f [ j - k ] = -1;
} 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 < > { string.getAlphabet ( ), rotated };
}
} /* namespace simplify */
} /* namespace string */
#endif /* _NORMALIZE_ROTATION_H__ */