/*
 * NormalizeAlphabet.h
 *
 *  Created on: Dec 9, 2013
 *	  Author: Jan Travnicek
 */

#ifndef NORMALIZE_ALPHABET_H_
#define NORMALIZE_ALPHABET_H_

#include <string/LinearString.h>

namespace string {

namespace simplify {

/**
 * Applies a homomorphism asigning characters 'a', 'b', ... to the first, second, ... occurring symbol in the string content
 */
class NormalizeAlphabet {
public:
	/**
	 * Applies a homomorphism asigning characters 'a', 'b', ... to the first, second, ... occurring symbol in the string content.
	 *
	 * \tparam SymbolType the type of symbols in the string
	 *
	 * \param str the input string
	 *
	 * \return the normalized string
	 */
	template < class SymbolType >
	static string::LinearString < std::string > normalize(const string::LinearString < SymbolType > & string);
};

template < class SymbolType >
string::LinearString < std::string > NormalizeAlphabet::normalize(const string::LinearString < SymbolType > & string) {
	char counter = 'a';
	ext::map<SymbolType, std::string > normalizationData;

	for(const SymbolType& symbol : string.getContent())
		if(normalizationData.find(symbol) == normalizationData.end())
			normalizationData.insert ( std::make_pair ( symbol, std::string ( 1, counter ++ ) ) );

	ext::set < std::string > alphabet;
	for(const auto& symbol : normalizationData) {
		alphabet.insert ( symbol.second );
	}

	ext::vector < std::string > data;
	for(const SymbolType& symbol : string.getContent()) {
		data.push_back ( normalizationData.find(symbol)->second );
	}

	return string::LinearString < std::string > ( alphabet, data );
}

} /* namespace simplify */

} /* namespace string */

#endif /* NORMALIZE_ALPHABET_H_ */
