Skip to content
Snippets Groups Projects
NormalizeRotation.h 2.09 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * 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
     */
    
    class NormalizeRotation {
    
    	 * 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;
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    	for ( size_t 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__ */