/*
 * LyndonFactoring.h
 *
 *  Created on: 30. 8. 2018
 *      Author: Jan Travnicek
 *
 * Based on code from https://cp-algorithms.com/string/lyndon_factorization.html
 */

#ifndef LYNDON_FACTORING_H_
#define LYNDON_FACTORING_H_

#include <string/LinearString.h>

namespace stringology {

namespace properties {

class LyndonFactoring {
public:
	/**
	 * Computes the lyndon factoring of a given nonempty string (Duval algorithm).
	 *
	 * @param string the nonempty string to factorize
	 * @return positions where the string is split to nyldon factors
	 */
	template < class SymbolType >
	static ext::vector < unsigned > factorize ( const string::LinearString < SymbolType > & string );

};

template < class SymbolType >
ext::vector < unsigned > LyndonFactoring::factorize ( const string::LinearString < SymbolType > & string ) {
	int n = string.getContent ( ).size ( );
	int i = 0;
	ext::vector < unsigned > factorization;

	while ( i < n ) {
		int j = i + 1;
		int k = i;
		while ( j < n && string.getContent ( ) [ k ] <= string.getContent ( ) [ j ] ) {
			if ( string.getContent ( ) [ k ] < string.getContent ( ) [ j ] )
				k = i;
			else
				k ++;
			j ++;
		}
		while ( i <= k ) {
			factorization.push_back ( i );
			i += j - k;
		}
	}

	return factorization;
}

} /* namespace properties */

} /* namespace stringology */

#endif /* LYNDON_FACTORING_H_ */
