-
Jan Trávníček authoredJan Trávníček authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
NormalizeRotation.h 1.87 KiB
/*
* 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 {
class NormalizeRotation {
public:
/**
* Performs conversion.
* @return left regular grammar equivalent to source automaton.
*/
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) {
/**
* Lexicographically least circular substrings,
* based on
* Kellogg S. Booth
* 1979,
* modified to working code by Ladislav Vagner
*/
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;
ext::vector < SymbolType > rotated;
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__ */