From cdb6f5149e8d7ec4aa0d5d2eb80c31db11f39eba Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Tue, 6 Jun 2017 18:54:12 +0200 Subject: [PATCH] expose comparison of strings --- acompare2/src/StringCompare.cpp | 80 ++++++++++++++++++++++++++++ acompare2/src/StringCompare.h | 50 ++++++++++++++++++ acompare2/src/acompare.cpp | 92 ++++++++++++++++++--------------- 3 files changed, 181 insertions(+), 41 deletions(-) create mode 100644 acompare2/src/StringCompare.cpp create mode 100644 acompare2/src/StringCompare.h diff --git a/acompare2/src/StringCompare.cpp b/acompare2/src/StringCompare.cpp new file mode 100644 index 0000000000..4946e9c3aa --- /dev/null +++ b/acompare2/src/StringCompare.cpp @@ -0,0 +1,80 @@ +/* + * StringCompare.cpp + * + * Created on: Apr 4, 2017 + * Author: Tomas Pecka + */ + +#include "StringCompare.h" + +#include "string/CyclicString.h" +#include "string/LinearString.h" + +bool StringCompare::testCompare ( const string::LinearString < > & a, const string::LinearString < > & b ) { + return a.getContent ( ) == b.getContent ( ) && a.getAlphabet ( ) == b.getAlphabet ( ); +} + +bool StringCompare::testCompare ( const string::CyclicString < > &, const string::CyclicString < > & ) { + throw "NYI"; +} + +template < class T > +void StringCompare::setCompare ( const std::set < T > a, const std::set < T > b ) { + std::set < T > aMinusB; + std::set_difference ( a.begin ( ), a.end ( ), b.begin ( ), b.end ( ), std::inserter ( aMinusB, aMinusB.begin ( ) ) ); + + std::set < T > bMinusA; + std::set_difference ( b.begin ( ), b.end ( ), a.begin ( ), a.end ( ), std::inserter ( bMinusA, bMinusA.begin ( ) ) ); + + for ( typename std::set < T >::const_iterator iter = aMinusB.begin ( ); iter != aMinusB.end ( ); iter++ ) + std::cout << "< " << * iter << std::endl; + + std::cout << "---" << std::endl; + + for ( typename std::set < T >::const_iterator iter = bMinusA.begin ( ); iter != bMinusA.end ( ); iter++ ) + std::cout << "> " << * iter << std::endl; +} + +template < class T > +void StringCompare::vectorCompare ( const std::vector < T > a, const std::vector < T > b ) { + std::vector < T > aMinusB; + std::set_difference ( a.begin ( ), a.end ( ), b.begin ( ), b.end ( ), std::inserter ( aMinusB, aMinusB.begin ( ) ) ); + + std::vector < T > bMinusA; + std::set_difference ( b.begin ( ), b.end ( ), a.begin ( ), a.end ( ), std::inserter ( bMinusA, bMinusA.begin ( ) ) ); + + for ( typename std::vector < T >::const_iterator iter = aMinusB.begin ( ); iter != aMinusB.end ( ); iter++ ) + std::cout << "< " << * iter << std::endl; + + std::cout << "---" << std::endl; + + for ( typename std::vector < T >::const_iterator iter = bMinusA.begin ( ); iter != bMinusA.end ( ); iter++ ) + std::cout << "> " << * iter << std::endl; +} + +void StringCompare::printCompare ( const string::CyclicString < > &, const string::CyclicString < > & ) { + throw "NYI"; +} + +void StringCompare::printCompare ( const string::LinearString < > & a, const string::LinearString < > & b ) { + std::cout << "StringCompare" << std::endl; + + if ( a.getAlphabet ( ) != b.getAlphabet ( ) ) { + std::cout << "Alphabet" << std::endl; + + StringCompare::setCompare ( a.getAlphabet ( ), b.getAlphabet ( ) ); + } + + if ( a.getContent ( ) != b.getContent ( ) ) { + std::cout << "Content" << std::endl; + + StringCompare::vectorCompare ( a.getContent ( ), b.getContent ( ) ); + } +} + +auto StringCompareLinear = StringCompare::RegistratorWrapper < int, string::LinearString < >, string::LinearString < > > ( StringCompare::compare ); +auto StringCompareCyclic = StringCompare::RegistratorWrapper < int, string::CyclicString < >, string::CyclicString < > > ( StringCompare::compare ); + +int StringCompare::compare ( const string::String & a, const string::String & b ) { + return dispatch ( a.getData ( ), b.getData ( ) ); +} diff --git a/acompare2/src/StringCompare.h b/acompare2/src/StringCompare.h new file mode 100644 index 0000000000..221c309c38 --- /dev/null +++ b/acompare2/src/StringCompare.h @@ -0,0 +1,50 @@ +/* + * StringCompare.h + * + * Created on: Apr 4, 2017 + * Author: Tomas Pecka + */ + +#ifndef STRING_COMPARE_H_ +#define STRING_COMPARE_H_ + +#include <core/multipleDispatch.hpp> +#include <ostream> + +#include <string/String.h> +#include <string/StringFeatures.h> + +#include <utility> +#include <vector> + +class StringCompare : public std::DoubleDispatch < StringCompare, int, const string::StringBase &, const string::StringBase & > { +private: + static bool testCompare ( const string::LinearString < > & a, const string::LinearString < > & b ); + static void printCompare ( const string::LinearString < > & a, const string::LinearString < > & b ); + + static bool testCompare ( const string::CyclicString < > & a, const string::CyclicString < > & b ); + static void printCompare ( const string::CyclicString < > & a, const string::CyclicString < > & b ); + + template < class T > + static void setCompare ( const std::set < T > a, const std::set < T > b ); + template < class T > + static void vectorCompare ( const std::vector < T > a, const std::vector < T > b ); + +public: + template < class T > + static int compare ( const T & a, const T & b ); + + static int compare ( const string::String & a, const string::String & b ); +}; + +template < class T > +int StringCompare::compare ( const T & a, const T & b ) { + if ( !StringCompare::testCompare ( a, b ) ) { + StringCompare::printCompare ( a, b ); + return 1; + } else { + return 0; + } +} + +#endif /* GRAMMAR_COMPARE_H_ */ diff --git a/acompare2/src/acompare.cpp b/acompare2/src/acompare.cpp index 16cf4db6e8..7a21066115 100644 --- a/acompare2/src/acompare.cpp +++ b/acompare2/src/acompare.cpp @@ -5,85 +5,95 @@ * Author: Jan Travnicek */ -#include <tclap/CmdLine.h> #include <global/GlobalData.h> #include <measure> #include <sax/FromXMLParserHelper.h> +#include <tclap/CmdLine.h> -#include "factory/XmlDataFactory.hpp" #include "exception/CommonException.h" +#include "factory/XmlDataFactory.hpp" #include "AutomatonCompare.h" #include "GrammarCompare.h" +#include "StringCompare.h" -int main(int argc, char** argv) { +int main ( int argc, char * * argv ) { try { common::GlobalData::argc = argc; common::GlobalData::argv = argv; - TCLAP::CmdLine cmd("Regexp derivative compute binary", ' ', "0.01"); + TCLAP::CmdLine cmd ( "Regexp derivative compute binary", ' ', "0.01" ); - TCLAP::UnlabeledValueArg<std::string> input1( "input1", "The first input to compare", true, "-", "file"); - cmd.add( input1 ); + TCLAP::UnlabeledValueArg < std::string > input1 ( "input1", "The first input to compare", true, "-", "file" ); + cmd.add ( input1 ); - TCLAP::UnlabeledValueArg<std::string> input2( "input2", "The second input to compare", true, "-", "file"); - cmd.add( input2 ); + TCLAP::UnlabeledValueArg < std::string > input2 ( "input2", "The second input to compare", true, "-", "file" ); + cmd.add ( input2 ); - TCLAP::SwitchArg measure( "m", "measure", "Measure times", false); - cmd.add( measure ); + TCLAP::SwitchArg measure ( "m", "measure", "Measure times", false ); + cmd.add ( measure ); - TCLAP::SwitchArg verbose( "v", "verbose", "Be verbose", false); - cmd.add( verbose ); + TCLAP::SwitchArg verbose ( "v", "verbose", "Be verbose", false ); + cmd.add ( verbose ); - cmd.parse(argc, argv); + cmd.parse ( argc, argv ); - if(verbose.isSet()) + if ( verbose.isSet ( ) ) common::GlobalData::verbose = true; - if(measure.isSet()) + + if ( measure.isSet ( ) ) common::GlobalData::measure = true; - measurements::start("Overal", measurements::Type::OVERALL); - measurements::start("Input read", measurements::Type::AUXILIARY); + measurements::start ( "Overal", measurements::Type::OVERALL ); + measurements::start ( "Input read", measurements::Type::AUXILIARY ); - std::deque<sax::Token> tokens1 = sax::FromXMLParserHelper::parseInput(input1); - std::deque<sax::Token> tokens2 = sax::FromXMLParserHelper::parseInput(input2); + std::deque < sax::Token > tokens1 = sax::FromXMLParserHelper::parseInput ( input1 ); + std::deque < sax::Token > tokens2 = sax::FromXMLParserHelper::parseInput ( input2 ); int res; - if(alib::XmlDataFactory::first<automaton::Automaton>(tokens1) && alib::XmlDataFactory::first<automaton::Automaton>(tokens2)) { - automaton::Automaton automaton1 = alib::XmlDataFactory::fromTokens (std::move(tokens1)); - automaton::Automaton automaton2 = alib::XmlDataFactory::fromTokens (std::move(tokens2)); + if ( alib::XmlDataFactory::first < automaton::Automaton > ( tokens1 ) && alib::XmlDataFactory::first < automaton::Automaton > ( tokens2 ) ) { + automaton::Automaton automaton1 = alib::XmlDataFactory::fromTokens ( std::move ( tokens1 ) ); + automaton::Automaton automaton2 = alib::XmlDataFactory::fromTokens ( std::move ( tokens2 ) ); + + measurements::end ( ); + measurements::start ( "Compare", measurements::Type::MAIN ); + + res = AutomatonCompare::compare ( automaton1, automaton2 ); + } else if ( alib::XmlDataFactory::first < grammar::Grammar > ( tokens1 ) && alib::XmlDataFactory::first < grammar::Grammar > ( tokens2 ) ) { + grammar::Grammar grammar1 = alib::XmlDataFactory::fromTokens ( std::move ( tokens1 ) ); + grammar::Grammar grammar2 = alib::XmlDataFactory::fromTokens ( std::move ( tokens2 ) ); - measurements::end(); - measurements::start("Compare", measurements::Type::MAIN); + measurements::end ( ); + measurements::start ( "Compare", measurements::Type::MAIN ); - res = AutomatonCompare::compare(automaton1, automaton2); - } else if(alib::XmlDataFactory::first<grammar::Grammar>(tokens1) && alib::XmlDataFactory::first<grammar::Grammar>(tokens2)) { - grammar::Grammar grammar1 = alib::XmlDataFactory::fromTokens (std::move(tokens1)); - grammar::Grammar grammar2 = alib::XmlDataFactory::fromTokens (std::move(tokens2)); + res = GrammarCompare::compare ( grammar1, grammar2 ); + } else if ( alib::XmlDataFactory::first < string::String > ( tokens1 ) && alib::XmlDataFactory::first < string::String > ( tokens2 ) ) { + string::String string1 = alib::XmlDataFactory::fromTokens ( std::move ( tokens1 ) ); + string::String string2 = alib::XmlDataFactory::fromTokens ( std::move ( tokens2 ) ); - measurements::end(); - measurements::start("Compare", measurements::Type::MAIN); + measurements::end ( ); + measurements::start ( "Compare", measurements::Type::MAIN ); - res = GrammarCompare::compare(grammar1, grammar2); + res = StringCompare::compare ( string1, string2 ); } else { - throw exception::CommonException("Only automata and grammars can be compared."); + throw exception::CommonException ( "Only automata, grammars and strings can be compared." ); } - measurements::end(); - measurements::end(); + measurements::end ( ); + measurements::end ( ); return res; - } catch (const exception::CommonException& exception) { - alib::XmlDataFactory::toStdout(exception); + } catch ( const exception::CommonException & exception ) { + alib::XmlDataFactory::toStdout ( exception ); return 1; - } catch(const TCLAP::ArgException& exception) { - std::cerr << exception.error() << std::endl; + } catch ( const TCLAP::ArgException & exception ) { + std::cerr << exception.error ( ) << std::endl; return 2; - } catch (const std::exception& exception) { - std::cerr << "Exception caught: " << exception.what() << std::endl; + } catch ( const std::exception & exception ) { + std::cerr << "Exception caught: " << exception.what ( ) << std::endl; return 3; - } catch(...) { + } catch ( ... ) { std::cerr << "Unknown exception caught." << std::endl; return 127; } -- GitLab