From 5405a02e10341acaac8c0765a010bfc1f11ffb76 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Fri, 11 Sep 2015 15:45:32 +0200 Subject: [PATCH] add LinearStringTerminatingSymbol --- alib2algo/src/string/naive/ExactCompare.cpp | 57 ++++--- alib2algo/src/string/naive/ExactEqual.cpp | 48 +++--- alib2data/src/string/CyclicString.h | 4 +- alib2data/src/string/LinearString.cpp | 152 +++++++++--------- alib2data/src/string/LinearString.h | 8 +- .../string/LinearStringTerminatingSymbol.cpp | 142 ++++++++++++++++ .../string/LinearStringTerminatingSymbol.h | 95 +++++++++++ .../TerminatingSymbolStringAlphabet.cpp | 53 ++++++ .../common/TerminatingSymbolStringAlphabet.h | 74 +++++++++ .../src/string/StringToStringComposer.cpp | 31 ++-- 10 files changed, 530 insertions(+), 134 deletions(-) create mode 100644 alib2data/src/string/LinearStringTerminatingSymbol.cpp create mode 100644 alib2data/src/string/LinearStringTerminatingSymbol.h create mode 100644 alib2data/src/string/common/TerminatingSymbolStringAlphabet.cpp create mode 100644 alib2data/src/string/common/TerminatingSymbolStringAlphabet.h diff --git a/alib2algo/src/string/naive/ExactCompare.cpp b/alib2algo/src/string/naive/ExactCompare.cpp index b72770486c..4a6b015ba9 100644 --- a/alib2algo/src/string/naive/ExactCompare.cpp +++ b/alib2algo/src/string/naive/ExactCompare.cpp @@ -8,58 +8,67 @@ #include "string/LinearString.h" #include "string/CyclicString.h" +#include "string/Epsilon.h" namespace string { namespace naive { -int ExactCompare::compare(const string::String& u, const string::String& v) { - return getInstance().dispatch(u.getData(), v.getData()); +int ExactCompare::compare ( const string::String & u, const string::String & v ) { + return getInstance ( ).dispatch ( u.getData ( ), v.getData ( ) ); } -int ExactCompare::compare(const string::Epsilon&, const string::Epsilon&) { +int ExactCompare::compare ( const string::Epsilon &, const string::Epsilon & ) { return 0; } -auto ExactCompareEpsilon = ExactCompare::RegistratorWrapper<int, string::Epsilon>(ExactCompare::getInstance(), ExactCompare::compare); +auto ExactCompareEpsilon = ExactCompare::RegistratorWrapper < int, string::Epsilon > ( ExactCompare::getInstance ( ), ExactCompare::compare ); -int ExactCompare::compare(const string::LinearString& u, const string::LinearString& v) { - int n = (int) u.getContent().size(), m = (int)v.getContent().size(); +int ExactCompare::compare ( const string::LinearString & u, const string::LinearString & v ) { + int n = ( int ) u.getContent ( ).size ( ), m = ( int ) v.getContent ( ).size ( ); int k = 0; - while(k < n && k < m && u.getContent()[k] == v.getContent()[k]) k++; - if (k == m && k == n) { + while ( k < n && k < m && u.getContent ( )[k] == v.getContent ( )[k] ) k++; + + if ( ( k == m ) && ( k == n ) ) return 0; - } else if(k == m) { + else if ( k == m ) return -1; - } else if(k == n) { + else if ( k == n ) return 1; - } else if(u.getContent()[k] < v.getContent()[k]) { + else if ( u.getContent ( )[k] < v.getContent ( )[k] ) return -1; - } else { + else return 1; - } } -auto ExactCompareLinearString = ExactCompare::RegistratorWrapper<int, string::LinearString>(ExactCompare::getInstance(), ExactCompare::compare); +auto ExactCompareLinearString = ExactCompare::RegistratorWrapper < int, string::LinearString > ( ExactCompare::getInstance ( ), ExactCompare::compare ); -int ExactCompare::compare(const string::CyclicString& u, const string::CyclicString& v) { - int n = (int) u.getContent().size(), m = (int)v.getContent().size(); +int ExactCompare::compare ( const string::CyclicString & u, const string::CyclicString & v ) { + int n = ( int ) u.getContent ( ).size ( ), m = ( int ) v.getContent ( ).size ( ); int i = -1, j = -1, k; bool last = 0; - while(i < n - 1 && j < m - 1) - { + + while ( i < n - 1 && j < m - 1 ) { k = 1; - while(k <= n && u.getContent()[(i + k) % n] == v.getContent()[(j + k) % m]) k++; - if (k > n) return 0; - last = u.getContent()[(i + k) % n] > v.getContent()[(j + k) % m]; - if (last) i += k; else j += k; + + while ( k <= n && u.getContent ( )[( i + k ) % n] == v.getContent ( )[( j + k ) % m] ) k++; + + if ( k > n ) return 0; + + last = u.getContent ( )[( i + k ) % n] > v.getContent ( )[( j + k ) % m]; + + if ( last ) + i += k; + else + j += k; } - return last ? 1 : - 1; + + return last ? 1 : -1; } -auto ExactCompareCyclicString = ExactCompare::RegistratorWrapper<int, string::CyclicString>(ExactCompare::getInstance(), ExactCompare::compare); +auto ExactCompareCyclicString = ExactCompare::RegistratorWrapper < int, string::CyclicString > ( ExactCompare::getInstance ( ), ExactCompare::compare ); } /* namespace naive */ diff --git a/alib2algo/src/string/naive/ExactEqual.cpp b/alib2algo/src/string/naive/ExactEqual.cpp index 412b4abf03..55b25283ea 100644 --- a/alib2algo/src/string/naive/ExactEqual.cpp +++ b/alib2algo/src/string/naive/ExactEqual.cpp @@ -8,51 +8,59 @@ #include "string/LinearString.h" #include "string/CyclicString.h" +#include "string/Epsilon.h" namespace string { namespace naive { -bool ExactEqual::equals(const string::String& u, const string::String& v) { - return getInstance().dispatch(u.getData(), v.getData()); +bool ExactEqual::equals ( const string::String & u, const string::String & v ) { + return getInstance ( ).dispatch ( u.getData ( ), v.getData ( ) ); } -bool ExactEqual::equals(const string::Epsilon&, const string::Epsilon&) { +bool ExactEqual::equals ( const string::Epsilon &, const string::Epsilon & ) { return true; } -auto ExactEqualEpsilon = ExactEqual::RegistratorWrapper<bool, string::Epsilon>(ExactEqual::getInstance(), ExactEqual::equals); +auto ExactEqualEpsilon = ExactEqual::RegistratorWrapper < bool, string::Epsilon > ( ExactEqual::getInstance ( ), ExactEqual::equals ); -bool ExactEqual::equals(const string::LinearString& u, const string::LinearString& v) { - int n = (int) u.getContent().size(), m = (int)v.getContent().size(); +bool ExactEqual::equals ( const string::LinearString & u, const string::LinearString & v ) { + int n = ( int ) u.getContent ( ).size ( ), m = ( int ) v.getContent ( ).size ( ); int k = 0; - while(k < n && k < m && u.getContent()[k] == v.getContent()[k]) k++; - if (k == m && k == n) { + while ( k < n && k < m && u.getContent ( )[k] == v.getContent ( )[k] ) k++; + + if ( ( k == m ) && ( k == n ) ) return true; - } else { + else return false; - } } -auto ExactEqualLinearString = ExactEqual::RegistratorWrapper<bool, string::LinearString>(ExactEqual::getInstance(), ExactEqual::equals); +auto ExactEqualLinearString = ExactEqual::RegistratorWrapper < bool, string::LinearString > ( ExactEqual::getInstance ( ), ExactEqual::equals ); -bool ExactEqual::equals(const string::CyclicString& u, const string::CyclicString& v) { - int n = (int)u.getContent().size(); +bool ExactEqual::equals ( const string::CyclicString & u, const string::CyclicString & v ) { + int n = ( int ) u.getContent ( ).size ( ); int i = -1, j = -1, k; - if (n != (int) v.getContent().size()) return false; - while(i < n - 1 && j < n - 1) - { + if ( n != ( int ) v.getContent ( ).size ( ) ) return false; + + while ( i < n - 1 && j < n - 1 ) { k = 1; - while(k <= n && u.getContent()[(i + k) % n] == v.getContent()[(j + k) % n]) k++; - if (k > n) return true; - if (u.getContent()[(i + k) % n] > v.getContent()[(j + k) % n]) i += k; else j += k; + + while ( k <= n && u.getContent ( )[( i + k ) % n] == v.getContent ( )[( j + k ) % n] ) k++; + + if ( k > n ) return true; + + if ( u.getContent ( )[( i + k ) % n] > v.getContent ( )[( j + k ) % n] ) + i += k; + else + j += k; } + return false; } -auto ExactEqualCyclicString = ExactEqual::RegistratorWrapper<bool, string::CyclicString>(ExactEqual::getInstance(), ExactEqual::equals); +auto ExactEqualCyclicString = ExactEqual::RegistratorWrapper < bool, string::CyclicString > ( ExactEqual::getInstance ( ), ExactEqual::equals ); } /* namespace naive */ diff --git a/alib2data/src/string/CyclicString.h b/alib2data/src/string/CyclicString.h index 1503a33830..83131a9a1d 100644 --- a/alib2data/src/string/CyclicString.h +++ b/alib2data/src/string/CyclicString.h @@ -15,10 +15,10 @@ #include "../alphabet/Symbol.h" #include "common/StringAlphabet.h" -#include "Epsilon.h" - namespace string { +class Epsilon; + /** * Represents regular expression parsed from the XML. Regular expression is stored * as a tree of CyclicStringElement. diff --git a/alib2data/src/string/LinearString.cpp b/alib2data/src/string/LinearString.cpp index 237ac193a6..d275307c13 100644 --- a/alib2data/src/string/LinearString.cpp +++ b/alib2data/src/string/LinearString.cpp @@ -7,6 +7,7 @@ #include "LinearString.h" #include "Epsilon.h" +#include "../tree/ranked/PrefixRankedTree.h" #include "../exception/AlibException.h" #include <sstream> @@ -22,133 +23,140 @@ namespace string { -LinearString::LinearString() { - +LinearString::LinearString ( ) { } -LinearString::LinearString(std::set<alphabet::Symbol> alphabet, std::vector<alphabet::Symbol> data) { - this->alphabet = std::move(alphabet); - setContent(std::move(data)); +LinearString::LinearString ( std::set < alphabet::Symbol > alphabet, std::vector < alphabet::Symbol > data ) { + this->alphabet = std::move ( alphabet ); + setContent ( std::move ( data ) ); } -LinearString::LinearString(std::vector<alphabet::Symbol> data) { - alphabet = std::set<alphabet::Symbol>(data.begin(), data.end()); - m_Data = std::move(data); +LinearString::LinearString ( std::vector < alphabet::Symbol > data ) { + alphabet = std::set < alphabet::Symbol > ( data.begin ( ), data.end ( ) ); + m_Data = std::move ( data ); } -LinearString::LinearString(const std::string& string) { - for(const char& symbol : string) { - m_Data.push_back( alphabet::symbolFrom( symbol ) ); - } - alphabet = std::set<alphabet::Symbol>(m_Data.begin(), m_Data.end()); +LinearString::LinearString ( const std::string & string ) { + for ( const char & symbol : string ) + m_Data.push_back ( alphabet::symbolFrom ( symbol ) ); + + alphabet = std::set < alphabet::Symbol > ( m_Data.begin ( ), m_Data.end ( ) ); } -LinearString::LinearString(const char* string) : LinearString((std::string) string) { +LinearString::LinearString ( const char * string ) : LinearString ( ( std::string ) string ) { } -LinearString::LinearString(const Epsilon& epsilon) { - alphabet = epsilon.getAlphabet(); +LinearString::LinearString ( const Epsilon & epsilon ) { + alphabet = epsilon.getAlphabet ( ); } -LinearString::LinearString(const tree::PrefixRankedTree& tree) { - for(const alphabet::RankedSymbol& symbol : tree.getAlphabet()) { - this->alphabet.insert(alphabet::Symbol(std::move(symbol))); - } - for(const alphabet::RankedSymbol& symbol : tree.getContent()) { - this->m_Data.push_back(alphabet::Symbol(symbol)); - } +LinearString::LinearString ( const tree::PrefixRankedTree & tree ) { + for ( const alphabet::RankedSymbol & symbol : tree.getAlphabet ( ) ) + this->alphabet.insert ( alphabet::Symbol ( std::move ( symbol ) ) ); + + for ( const alphabet::RankedSymbol & symbol : tree.getContent ( ) ) + this->m_Data.push_back ( alphabet::Symbol ( symbol ) ); } -StringBase* LinearString::clone() const { - return new LinearString(*this); +StringBase * LinearString::clone ( ) const { + return new LinearString ( * this ); } -StringBase* LinearString::plunder() && { - return new LinearString(std::move(*this)); +StringBase * LinearString::plunder ( ) && { + return new LinearString ( std::move ( * this ) ); } -bool LinearString::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) { - if(std::any_of(m_Data.begin(), m_Data.end(), [&](const alphabet::Symbol & s) { return s == symbol; } ) ) - throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is used."); +bool LinearString::removeSymbolFromAlphabet ( const alphabet::Symbol & symbol ) { + if ( std::any_of ( m_Data.begin ( ), m_Data.end ( ), [&] ( const alphabet::Symbol & s ) { + return s == symbol; + } ) ) + throw exception::AlibException ( "Input symbol \"" + ( std::string ) symbol + "\" is used." ); - return alphabet.erase(symbol); + return alphabet.erase ( symbol ); } -void LinearString::appendSymbol(alphabet::Symbol symbol) { - if(alphabet.count(symbol) == 0) - throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" not in the alphabet."); - m_Data.push_back(std::move(symbol)); +void LinearString::appendSymbol ( alphabet::Symbol symbol ) { + if ( alphabet.count ( symbol ) == 0 ) + throw exception::AlibException ( "Input symbol \"" + ( std::string ) symbol + "\" not in the alphabet." ); + + m_Data.push_back ( std::move ( symbol ) ); } -const std::vector<alphabet::Symbol>& LinearString::getContent() const { +const std::vector < alphabet::Symbol > & LinearString::getContent ( ) const { return this->m_Data; } -void LinearString::setContent(std::vector<alphabet::Symbol> data) { - std::set<alphabet::Symbol> minimalAlphabet(data.begin(), data.end()); - std::set<alphabet::Symbol> unknownSymbols; - std::set_difference(minimalAlphabet.begin(), minimalAlphabet.end(), alphabet.begin(), alphabet.end(), std::inserter(unknownSymbols, unknownSymbols.end())); +void LinearString::setContent ( std::vector < alphabet::Symbol > data ) { + std::set < alphabet::Symbol > minimalAlphabet ( data.begin ( ), data.end ( ) ); + std::set < alphabet::Symbol > unknownSymbols; + std::set_difference ( minimalAlphabet.begin ( ), minimalAlphabet.end ( ), alphabet.begin ( ), alphabet.end ( ), std::inserter ( unknownSymbols, unknownSymbols.end ( ) ) ); - if(unknownSymbols.size() > 0) - throw exception::AlibException("Input symbols not in the alphabet."); + if ( unknownSymbols.size ( ) > 0 ) + throw exception::AlibException ( "Input symbols not in the alphabet." ); - this->m_Data = std::move(data); + this->m_Data = std::move ( data ); } -bool LinearString::isEmpty() const { - return this->m_Data.size() == 0; +bool LinearString::isEmpty ( ) const { + return this->m_Data.size ( ) == 0; } -int LinearString::compare(const LinearString& other) const { - auto first = std::tie(m_Data, alphabet); - auto second = std::tie(other.m_Data, other.alphabet); +int LinearString::compare ( const LinearString & other ) const { + auto first = std::tie ( m_Data, alphabet ); + auto second = std::tie ( other.m_Data, other.alphabet ); + + std::compare < decltype ( first ) > comp; - std::compare<decltype(first)> comp; - return comp(first, second); + return comp ( first, second ); } -void LinearString::operator >>(std::ostream& out) const { +void LinearString::operator >>( std::ostream & out ) const { out << "(LinearString "; - for(const alphabet::Symbol& symbol : this->m_Data) + + for ( const alphabet::Symbol & symbol : this->m_Data ) out << symbol; + out << ")"; } -LinearString::operator std::string () const { +LinearString::operator std::string ( ) const { std::stringstream ss; ss << "\""; - for(const alphabet::Symbol& symbol : this->m_Data) - ss << (std::string) symbol; + + for ( const alphabet::Symbol & symbol : this->m_Data ) + ss << ( std::string ) symbol; + ss << "\""; - return std::move(ss).str(); + return std::move ( ss ).str ( ); } const std::string LinearString::XML_TAG_NAME = "LinearString"; -LinearString LinearString::parse(std::deque<sax::Token>::iterator& input) { - sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::START_ELEMENT, LinearString::XML_TAG_NAME); - std::set<alphabet::Symbol> alphabet = StringFromXMLParser::parseAlphabet(input); - std::vector<alphabet::Symbol> content = StringFromXMLParser::parseContent(input); - sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, LinearString::XML_TAG_NAME); - return LinearString(alphabet, content); +LinearString LinearString::parse ( std::deque < sax::Token >::iterator & input ) { + sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, LinearString::XML_TAG_NAME ); + std::set < alphabet::Symbol > alphabet = StringFromXMLParser::parseAlphabet ( input ); + std::vector < alphabet::Symbol > content = StringFromXMLParser::parseContent ( input ); + sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, LinearString::XML_TAG_NAME ); + + return LinearString ( alphabet, content ); } -void LinearString::compose(std::deque<sax::Token>& out) const { - out.emplace_back(LinearString::XML_TAG_NAME, sax::Token::TokenType::START_ELEMENT); - StringToXMLComposer::compose(out, alphabet); - StringToXMLComposer::compose(out, m_Data); - out.emplace_back(LinearString::XML_TAG_NAME, sax::Token::TokenType::END_ELEMENT); +void LinearString::compose ( std::deque < sax::Token > & out ) const { + out.emplace_back ( LinearString::XML_TAG_NAME, sax::Token::TokenType::START_ELEMENT ); + StringToXMLComposer::compose ( out, alphabet ); + StringToXMLComposer::compose ( out, m_Data ); + out.emplace_back ( LinearString::XML_TAG_NAME, sax::Token::TokenType::END_ELEMENT ); } } /* namespace string */ namespace alib { -xmlApi<string::String>::ParserRegister<string::LinearString> linearStringParserRegister = xmlApi<string::String>::ParserRegister<string::LinearString>(string::LinearString::XML_TAG_NAME, string::LinearString::parse); -xmlApi<alib::Object>::ParserRegister<string::LinearString> linearStringParserRegister2 = xmlApi<alib::Object>::ParserRegister<string::LinearString>(string::LinearString::XML_TAG_NAME, string::LinearString::parse); +xmlApi < string::String >::ParserRegister < string::LinearString > linearStringParserRegister = xmlApi < string::String >::ParserRegister < string::LinearString > ( string::LinearString::XML_TAG_NAME, string::LinearString::parse ); +xmlApi < alib::Object >::ParserRegister < string::LinearString > linearStringParserRegister2 = xmlApi < alib::Object >::ParserRegister < string::LinearString > ( string::LinearString::XML_TAG_NAME, string::LinearString::parse ); -auto LinearStringFromEpsilon = castApi::CastRegister<string::LinearString, string::Epsilon>(); -auto LinearStringFromPrefixRankedTree = castApi::CastRegister<string::LinearString, tree::PrefixRankedTree>(); -auto LinearStringCastBinder = castApi::CastPoolStringBinder<string::LinearString>(string::LinearString::XML_TAG_NAME); +auto LinearStringFromEpsilon = castApi::CastRegister < string::LinearString, string::Epsilon > ( ); +auto LinearStringFromPrefixRankedTree = castApi::CastRegister < string::LinearString, tree::PrefixRankedTree > ( ); +auto LinearStringCastBinder = castApi::CastPoolStringBinder < string::LinearString > ( string::LinearString::XML_TAG_NAME ); } /* namespace alib */ diff --git a/alib2data/src/string/LinearString.h b/alib2data/src/string/LinearString.h index 1998501588..8b4445c895 100644 --- a/alib2data/src/string/LinearString.h +++ b/alib2data/src/string/LinearString.h @@ -15,12 +15,16 @@ #include "../alphabet/Symbol.h" #include "common/StringAlphabet.h" -#include "../tree/ranked/PrefixRankedTree.h" -#include "Epsilon.h" +namespace tree { + +class PrefixRankedTree; +} namespace string { +class Epsilon; + /** * Represents regular expression parsed from the XML. Regular expression is stored * as a tree of LinearStringElement. diff --git a/alib2data/src/string/LinearStringTerminatingSymbol.cpp b/alib2data/src/string/LinearStringTerminatingSymbol.cpp new file mode 100644 index 0000000000..f1b596a3f4 --- /dev/null +++ b/alib2data/src/string/LinearStringTerminatingSymbol.cpp @@ -0,0 +1,142 @@ +/* + * LinearStringTerminatingSymbol.cpp + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#include "LinearStringTerminatingSymbol.h" +#include "LinearString.h" +#include "../exception/AlibException.h" + +#include <sstream> +#include <algorithm> + +#include "../sax/FromXMLParserHelper.h" +#include "common/StringFromXMLParser.h" +#include "common/StringToXMLComposer.h" +#include "String.h" +#include "../object/Object.h" +#include "../XmlApi.hpp" +#include "../CastApi.hpp" + +namespace string { + +LinearStringTerminatingSymbol::LinearStringTerminatingSymbol ( alphabet::Symbol terminatingSymbol ) : TerminatingSymbolStringAlphabet ( std::move ( terminatingSymbol ) ) { +} + +LinearStringTerminatingSymbol::LinearStringTerminatingSymbol ( std::set < alphabet::Symbol > alphabet, alphabet::Symbol terminatingSymbol, std::vector < alphabet::Symbol > data ) : TerminatingSymbolStringAlphabet ( std::move ( terminatingSymbol ) ) { + this->alphabet = std::move ( alphabet ); + setContent ( std::move ( data ) ); +} + +LinearStringTerminatingSymbol::LinearStringTerminatingSymbol ( alphabet::Symbol terminatingSymbol, std::vector < alphabet::Symbol > data ) : TerminatingSymbolStringAlphabet ( std::move ( terminatingSymbol ) ) { + alphabet = std::set < alphabet::Symbol > ( data.begin ( ), data.end ( ) ); + m_Data = std::move ( data ); +} + +LinearStringTerminatingSymbol::LinearStringTerminatingSymbol ( alphabet::Symbol terminatingSymbol, const LinearString & string ) : TerminatingSymbolStringAlphabet ( std::move ( terminatingSymbol ) ) { + alphabet = string.getAlphabet ( ); + m_Data = string.getContent ( ); +} + +StringBase * LinearStringTerminatingSymbol::clone ( ) const { + return new LinearStringTerminatingSymbol ( * this ); +} + +StringBase * LinearStringTerminatingSymbol::plunder ( ) && { + return new LinearStringTerminatingSymbol ( std::move ( * this ) ); +} + +bool LinearStringTerminatingSymbol::removeSymbolFromAlphabet ( const alphabet::Symbol & symbol ) { + if ( std::any_of ( m_Data.begin ( ), m_Data.end ( ), [&] ( const alphabet::Symbol & s ) { + return s == symbol; + } ) ) + throw exception::AlibException ( "Input symbol \"" + ( std::string ) symbol + "\" is used." ); + + return alphabet.erase ( symbol ); +} + +void LinearStringTerminatingSymbol::appendSymbol ( alphabet::Symbol symbol ) { + if ( alphabet.count ( symbol ) == 0 ) + throw exception::AlibException ( "Input symbol \"" + ( std::string ) symbol + "\" not in the alphabet." ); + + m_Data.push_back ( std::move ( symbol ) ); +} + +const std::vector < alphabet::Symbol > & LinearStringTerminatingSymbol::getContent ( ) const { + return this->m_Data; +} + +void LinearStringTerminatingSymbol::setContent ( std::vector < alphabet::Symbol > data ) { + std::set < alphabet::Symbol > minimalAlphabet ( data.begin ( ), data.end ( ) ); + std::set < alphabet::Symbol > unknownSymbols; + std::set_difference ( minimalAlphabet.begin ( ), minimalAlphabet.end ( ), alphabet.begin ( ), alphabet.end ( ), std::inserter ( unknownSymbols, unknownSymbols.end ( ) ) ); + + if ( unknownSymbols.size ( ) > 0 ) + throw exception::AlibException ( "Input symbols not in the alphabet." ); + + this->m_Data = std::move ( data ); +} + +bool LinearStringTerminatingSymbol::isEmpty ( ) const { + return this->m_Data.size ( ) == 0; +} + +int LinearStringTerminatingSymbol::compare ( const LinearStringTerminatingSymbol & other ) const { + auto first = std::tie ( m_Data, alphabet ); + auto second = std::tie ( other.m_Data, other.alphabet ); + + std::compare < decltype ( first ) > comp; + + return comp ( first, second ); +} + +void LinearStringTerminatingSymbol::operator >>( std::ostream & out ) const { + out << "(LinearStringTerminatingSymbol "; + + for ( const alphabet::Symbol & symbol : this->m_Data ) + out << symbol; + + out << ")"; +} + +LinearStringTerminatingSymbol::operator std::string ( ) const { + std::stringstream ss; + ss << "\""; + + for ( const alphabet::Symbol & symbol : this->m_Data ) + ss << ( std::string ) symbol; + + ss << "\""; + return std::move ( ss ).str ( ); +} + +const std::string LinearStringTerminatingSymbol::XML_TAG_NAME = "LinearStringTerminatingSymbol"; + +LinearStringTerminatingSymbol LinearStringTerminatingSymbol::parse ( std::deque < sax::Token >::iterator & input ) { + sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, LinearStringTerminatingSymbol::XML_TAG_NAME ); + std::set < alphabet::Symbol > alphabet = StringFromXMLParser::parseAlphabet ( input ); + alphabet::Symbol terminatingSymbol = alib::xmlApi < alphabet::Symbol >::parse ( input ); + std::vector < alphabet::Symbol > content = StringFromXMLParser::parseContent ( input ); + sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, LinearStringTerminatingSymbol::XML_TAG_NAME ); + + return LinearStringTerminatingSymbol ( alphabet, terminatingSymbol, content ); +} + +void LinearStringTerminatingSymbol::compose ( std::deque < sax::Token > & out ) const { + out.emplace_back ( LinearStringTerminatingSymbol::XML_TAG_NAME, sax::Token::TokenType::START_ELEMENT ); + StringToXMLComposer::compose ( out, alphabet ); + alib::xmlApi < alphabet::Symbol >::compose ( out, terminatingSymbol ); + StringToXMLComposer::compose ( out, m_Data ); + out.emplace_back ( LinearStringTerminatingSymbol::XML_TAG_NAME, sax::Token::TokenType::END_ELEMENT ); +} + +} /* namespace string */ + +namespace alib { + +xmlApi < string::String >::ParserRegister < string::LinearStringTerminatingSymbol > linearStringTerminatingSymbolParserRegister = xmlApi < string::String >::ParserRegister < string::LinearStringTerminatingSymbol > ( string::LinearStringTerminatingSymbol::XML_TAG_NAME, string::LinearStringTerminatingSymbol::parse ); +xmlApi < alib::Object >::ParserRegister < string::LinearStringTerminatingSymbol > linearStringTerminatingSymbolParserRegister2 = xmlApi < alib::Object >::ParserRegister < string::LinearStringTerminatingSymbol > ( string::LinearStringTerminatingSymbol::XML_TAG_NAME, string::LinearStringTerminatingSymbol::parse ); + +} /* namespace alib */ diff --git a/alib2data/src/string/LinearStringTerminatingSymbol.h b/alib2data/src/string/LinearStringTerminatingSymbol.h new file mode 100644 index 0000000000..5dcb3172e5 --- /dev/null +++ b/alib2data/src/string/LinearStringTerminatingSymbol.h @@ -0,0 +1,95 @@ +/* + * LinearStringTerminatingSymbol.h + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#ifndef LINEAR_STRING_TERMINATING_SYMBOL_H_ +#define LINEAR_STRING_TERMINATING_SYMBOL_H_ + +#include "StringBase.h" +#include <iostream> +#include <set> +#include <vector> + +#include "../alphabet/Symbol.h" +#include "common/TerminatingSymbolStringAlphabet.h" + +namespace string { + +class LinearString; + +/** + * Represents regular expression parsed from the XML. Regular expression is stored + * as a tree of LinearStringElement. + */ +class LinearStringTerminatingSymbol : public StringBase, public TerminatingSymbolStringAlphabet { + std::vector < alphabet::Symbol > m_Data; + +public: + explicit LinearStringTerminatingSymbol ( alphabet::Symbol terminatingSymbol ); + explicit LinearStringTerminatingSymbol ( std::set < alphabet::Symbol > alphabet, alphabet::Symbol terminatingSymbol, std::vector < alphabet::Symbol > data ); + explicit LinearStringTerminatingSymbol ( alphabet::Symbol terminatingSymbol, std::vector < alphabet::Symbol > data ); + explicit LinearStringTerminatingSymbol ( alphabet::Symbol terminatingSymbol, const LinearString & string ); + + virtual StringBase * clone ( ) const; + virtual StringBase * plunder ( ) &&; + + virtual const std::set < alphabet::Symbol > & getAlphabet ( ) const { + return TerminatingSymbolStringAlphabet::getAlphabet ( ); + } + + virtual bool removeSymbolFromAlphabet ( const alphabet::Symbol & symbol ); + + /** + * @param element to append + */ + void appendSymbol ( alphabet::Symbol symbol ); + + /** + * @return List of symbols forming string (const version). + */ + const std::vector < alphabet::Symbol > & getContent ( ) const; + + void setContent ( std::vector < alphabet::Symbol > data ); + + /** + * @return true if string is an empty word (vector length is 0) + */ + bool isEmpty ( ) const; + + virtual int compare ( const ObjectBase & other ) const { + if ( std::type_index ( typeid ( * this ) ) == std::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other ); + + return std::type_index ( typeid ( * this ) ) - std::type_index ( typeid ( other ) ); + } + + virtual int compare ( const LinearStringTerminatingSymbol & other ) const; + + virtual void operator >>( std::ostream & out ) const; + + virtual explicit operator std::string ( ) const; + + const static std::string XML_TAG_NAME; + + static LinearStringTerminatingSymbol parse ( std::deque < sax::Token >::iterator & input ); + + void compose ( std::deque < sax::Token > & out ) const; +}; + +} /* namespace string */ + +namespace std { + +template < > +struct compare < ::string::LinearStringTerminatingSymbol > { + int operator ()( const::string::LinearStringTerminatingSymbol & first, const::string::LinearStringTerminatingSymbol & second ) const { + return first.compare ( second ); + } + +}; + +} /* namespace std */ + +#endif /* LINEAR_STRING_TERMINATING_SYMBOL_H_ */ diff --git a/alib2data/src/string/common/TerminatingSymbolStringAlphabet.cpp b/alib2data/src/string/common/TerminatingSymbolStringAlphabet.cpp new file mode 100644 index 0000000000..9cc3b833a3 --- /dev/null +++ b/alib2data/src/string/common/TerminatingSymbolStringAlphabet.cpp @@ -0,0 +1,53 @@ +/* + * TerminatingSymbolStringAlphabet.cpp + * + * Created on: Apr 16, 2013 + * Author: Jan Travnicek + */ + +#include "TerminatingSymbolStringAlphabet.h" +#include "../../exception/AlibException.h" + +#include <algorithm> + +namespace string { + +TerminatingSymbolStringAlphabet::TerminatingSymbolStringAlphabet ( alphabet::Symbol terminatingSymbol ) : terminatingSymbol ( terminatingSymbol ) { + addSymbolToAlphabet ( std::move ( terminatingSymbol ) ); +} + +const std::set < alphabet::Symbol > & TerminatingSymbolStringAlphabet::getAlphabet ( ) const { + return alphabet; +} + +bool TerminatingSymbolStringAlphabet::addSymbolToAlphabet ( alphabet::Symbol symbol ) { + return alphabet.insert ( std::move ( symbol ) ).second; +} + +void TerminatingSymbolStringAlphabet::addSymbolsToAlphabet ( const std::set < alphabet::Symbol > & symbols ) { + for ( const alphabet::Symbol & addedSymbol : symbols ) + addSymbolToAlphabet ( addedSymbol ); +} + +void TerminatingSymbolStringAlphabet::setAlphabet ( std::set < alphabet::Symbol > newSymbols ) { + std::set < alphabet::Symbol > removed; + std::set_difference ( alphabet.begin ( ), alphabet.end ( ), newSymbols.begin ( ), newSymbols.end ( ), std::inserter ( removed, removed.end ( ) ) ); + + for ( const alphabet::Symbol & removedSymbol : removed ) + removeSymbolFromAlphabet ( removedSymbol ); + + alphabet = std::move ( newSymbols ); +} + +void TerminatingSymbolStringAlphabet::setTerminatingSymbol ( alphabet::Symbol terminatingSymbol ) { + if ( !alphabet.count ( terminatingSymbol ) ) + throw exception::AlibException ( "Symbol " + ( std::string ) terminatingSymbol + " cannot be set as terminating symbol. It is not present in the alphabet." ); + + terminatingSymbol = std::move ( terminatingSymbol ); +} + +const alphabet::Symbol & TerminatingSymbolStringAlphabet::getTerminatingSymbol ( ) const { + return terminatingSymbol; +} + +} /* namespace string */ diff --git a/alib2data/src/string/common/TerminatingSymbolStringAlphabet.h b/alib2data/src/string/common/TerminatingSymbolStringAlphabet.h new file mode 100644 index 0000000000..d0348452b9 --- /dev/null +++ b/alib2data/src/string/common/TerminatingSymbolStringAlphabet.h @@ -0,0 +1,74 @@ +/* + * StringAlphabet.h + * + * Created on: Apr 10, 2013 + * Author: Jan Travnicek + */ + +#ifndef TERMINATING_SYMBOL_STRING_ALPHABET_H_ +#define TERMINATING_SYMBOL_STRING_ALPHABET_H_ + +#include <set> +#include "../../alphabet/Symbol.h" + +namespace string { + +/** + * Abstract base class for all strings. Contains common elements of strings. + */ +class TerminatingSymbolStringAlphabet { +protected: + std::set < alphabet::Symbol > alphabet; + + alphabet::Symbol terminatingSymbol; + +public: + TerminatingSymbolStringAlphabet ( alphabet::Symbol terminatingSymbol ); + + /** + * Adds input symbol to input alphabet. + * @param symbol Symbol to add + */ + bool addSymbolToAlphabet ( alphabet::Symbol symbol ); + + /** + * Adds input symbols to input alphabet. + * @param symbols Symbol to add + */ + void addSymbolsToAlphabet ( const std::set < alphabet::Symbol > & symbols ); + + /** + * Sets input symbols of the string. + * @param symbols Symbols to set + */ + void setAlphabet ( std::set < alphabet::Symbol > symbols ); + + /** + * Removes input symbol from the input alphabet. + * @param symbol Symbol to remove + * @throws AutomatonException when symbol is not present in input alphabet + * or when symbol is part of the transition + */ + virtual bool removeSymbolFromAlphabet ( const alphabet::Symbol & symbol ) = 0; + + /** + * @return the input alphabet + */ + const std::set < alphabet::Symbol > & getAlphabet ( ) const; + + /** + * Set terminating symbol. + * @param terminatingSymbol alphabet::Symbol to set + * @throws AlibException when state is not present in the alphabet + */ + void setTerminatingSymbol ( alphabet::Symbol terminatinSymbol ); + + /** + * @return terminating symbol + */ + const alphabet::Symbol & getTerminatingSymbol ( ) const; +}; + +} /* namespace string */ + +#endif /* TERMINATING_SYMBOL_STRING_ALPHABET_H_ */ diff --git a/alib2str/src/string/StringToStringComposer.cpp b/alib2str/src/string/StringToStringComposer.cpp index ef5f407f96..eabd25672f 100644 --- a/alib2str/src/string/StringToStringComposer.cpp +++ b/alib2str/src/string/StringToStringComposer.cpp @@ -8,39 +8,42 @@ #include "StringToStringComposer.h" #include "string/CyclicString.h" #include "string/LinearString.h" +#include "string/Epsilon.h" #include "../StringApi.hpp" namespace string { -void StringToStringComposer::compose(std::ostream& out, const CyclicString& string) { +void StringToStringComposer::compose ( std::ostream & out, const CyclicString & string ) { out << "<"; - for(const auto& symbol : string.getContent()) { - alib::stringApi<alphabet::Symbol>::compose(out, symbol); - } + + for ( const auto & symbol : string.getContent ( ) ) + alib::stringApi < alphabet::Symbol >::compose ( out, symbol ); + out << ">"; } -StringToStringComposer::RegistratorWrapper<void, CyclicString> StringToStringComposerCyclicString = StringToStringComposer::RegistratorWrapper<void, CyclicString>(StringToStringComposer::getInstance(), StringToStringComposer::compose); +StringToStringComposer::RegistratorWrapper < void, CyclicString > StringToStringComposerCyclicString = StringToStringComposer::RegistratorWrapper < void, CyclicString > ( StringToStringComposer::getInstance ( ), StringToStringComposer::compose ); -void StringToStringComposer::compose(std::ostream& out, const LinearString& string) { +void StringToStringComposer::compose ( std::ostream & out, const LinearString & string ) { out << "\""; - for(const auto& symbol : string.getContent()) { - alib::stringApi<alphabet::Symbol>::compose(out, symbol); - } + + for ( const auto & symbol : string.getContent ( ) ) + alib::stringApi < alphabet::Symbol >::compose ( out, symbol ); + out << "\""; } -StringToStringComposer::RegistratorWrapper<void, LinearString> StringToStringComposerLinearString = StringToStringComposer::RegistratorWrapper<void, LinearString>(StringToStringComposer::getInstance(), StringToStringComposer::compose); +StringToStringComposer::RegistratorWrapper < void, LinearString > StringToStringComposerLinearString = StringToStringComposer::RegistratorWrapper < void, LinearString > ( StringToStringComposer::getInstance ( ), StringToStringComposer::compose ); -void StringToStringComposer::compose(std::ostream& out, const Epsilon&) { +void StringToStringComposer::compose ( std::ostream & out, const Epsilon & ) { out << "#E"; } -StringToStringComposer::RegistratorWrapper<void, Epsilon> StringToStringComposerEpsilon = StringToStringComposer::RegistratorWrapper<void, Epsilon>(StringToStringComposer::getInstance(), StringToStringComposer::compose); +StringToStringComposer::RegistratorWrapper < void, Epsilon > StringToStringComposerEpsilon = StringToStringComposer::RegistratorWrapper < void, Epsilon > ( StringToStringComposer::getInstance ( ), StringToStringComposer::compose ); -void StringToStringComposer::compose(std::ostream& out, const String& string) { - getInstance().dispatch(out, string.getData()); +void StringToStringComposer::compose ( std::ostream & out, const String & string ) { + getInstance ( ).dispatch ( out, string.getData ( ) ); } } /* namespace string */ -- GitLab