diff --git a/alib2algo/src/compare/string/CyclicStringCompare.cpp b/alib2algo/src/compare/string/CyclicStringCompare.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9c15baa629b4118c6f8ce25e9c9eb864cbf305a3 --- /dev/null +++ b/alib2algo/src/compare/string/CyclicStringCompare.cpp @@ -0,0 +1,41 @@ +/* + * CyclicStringCompare.cpp + * + * Created on: Oct 9, 2014 + * Author: RadomĂr Polcáh */ + +#include "CyclicStringCompare.h" + +namespace compare { + +bool CyclicStringCompare::equals(const string::LinearString& u, const string::LinearString& v) { + int n = (int)u.getContent().size(); + int i = -1, j = -1, k; + if (n != 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; + } + return false; +} + +int CyclicStringCompare::compare(const string::LinearString& u, const string::LinearString& 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) + { + k = 1; + while(k <= n && u.getContent()[(i + k) % n] == v.getContent()[(j + k) % m]) k++; + if (k > n) return 0; + if (last = u.getContent()[(i + k) % n] > v.getContent()[(j + k) % m]) i += k; else j += k; + } + return last ? 1 : - 1; +} + +} diff --git a/alib2algo/src/compare/string/CyclicStringCompare.h b/alib2algo/src/compare/string/CyclicStringCompare.h new file mode 100644 index 0000000000000000000000000000000000000000..5b8cb145184df12139912721779b3bd913a064b4 --- /dev/null +++ b/alib2algo/src/compare/string/CyclicStringCompare.h @@ -0,0 +1,24 @@ +/* + * CyclicStringCompare.h + * + * Created on: Oct 14, 2014 + * Author: RadomĂr Polách + */ + +#ifndef CYCLIC_STRING_COMPARE_H_ +#define CYCLIC_STRING_COMPARE_H_ + +#include "string/LinearString.h" + +namespace compare { + +class CyclicStringCompare { +public: + static bool equals(const string::LinearString& u, const string::LinearString& v); + static int compare(const string::LinearString& u, const string::LinearString& v); + +}; + +} + +#endif /* CYCLIC_STRING_COMPARE_H_ */ diff --git a/alib2algo/test-src/compare/compareTest.cpp b/alib2algo/test-src/compare/compareTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ada8b24b774329e4cdd2df6d348854630fcb378 --- /dev/null +++ b/alib2algo/test-src/compare/compareTest.cpp @@ -0,0 +1,33 @@ +#include <list> +#include "compareTest.h" + +#include "compare/string/CyclicStringCompare.h" +#include "string/LinearString.h" + +#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) + +CPPUNIT_TEST_SUITE_REGISTRATION( compareTest ); + +void compareTest::setUp() { +} + +void compareTest::tearDown() { +} + +void compareTest::testCyclicStringCompareBoolean() { + string::LinearString str1("alfa"); + string::LinearString str2("aalf"); + str2.addSymbolsToAlphabet(str1.getAlphabet()); + str1.addSymbolsToAlphabet(str2.getAlphabet()); + + CPPUNIT_ASSERT(compare::CyclicStringCompare::equals(str1, str2)); +} + +void compareTest::testCyclicStringCompareInt() { + string::LinearString str1("alfa"); + string::LinearString str2("aalf"); + str2.addSymbolsToAlphabet(str1.getAlphabet()); + str1.addSymbolsToAlphabet(str2.getAlphabet()); + + CPPUNIT_ASSERT(compare::CyclicStringCompare::compare(str1, str2) == 0); +} diff --git a/alib2algo/test-src/compare/compareTest.h b/alib2algo/test-src/compare/compareTest.h new file mode 100644 index 0000000000000000000000000000000000000000..9238a15e2b4eb39231cf7feb318bd493782767c0 --- /dev/null +++ b/alib2algo/test-src/compare/compareTest.h @@ -0,0 +1,21 @@ +#ifndef COMPARE_TEST_H_ +#define COMPARE_TEST_H_ + +#include <cppunit/extensions/HelperMacros.h> + +class compareTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( compareTest ); + CPPUNIT_TEST( testCyclicStringCompareBoolean ); + CPPUNIT_TEST( testCyclicStringCompareInt ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testCyclicStringCompareBoolean(); + void testCyclicStringCompareInt(); +}; + +#endif // COMPARE_TEST_H_ diff --git a/alib2data/src/string/CyclicString.cpp b/alib2data/src/string/CyclicString.cpp index fcf1fc8e582763619901c6b5e45df492b7e793fd..a0903dca5b8adf231acfd23c39606c820a765784 100644 --- a/alib2data/src/string/CyclicString.cpp +++ b/alib2data/src/string/CyclicString.cpp @@ -7,6 +7,9 @@ #include "CyclicString.h" #include "../exception/AlibException.h" +#include "../label/Label.h" +#include "../label/CharacterLabel.h" +#include "../alphabet/LabeledSymbol.h" #include <cassert> #include <sstream> @@ -43,6 +46,14 @@ CyclicString::CyclicString(std::vector<alphabet::Symbol>&& data) { setContent(std::move(data)); } +CyclicString::CyclicString(const std::string& str) { + for (unsigned i = 0; i < str.length(); ++i) + { + m_Data.push_back(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::CharacterLabel(str[i]))))); + } + alphabet = std::set<alphabet::Symbol>(m_Data.begin(), m_Data.end()); +} + StringBase* CyclicString::clone() const { return new CyclicString(*this); } diff --git a/alib2data/src/string/CyclicString.h b/alib2data/src/string/CyclicString.h index c1b4aef3442a7e339045c909b57b75bbd271ce3e..7173b9790d696b969328a197b8a175a1c22a0e05 100644 --- a/alib2data/src/string/CyclicString.h +++ b/alib2data/src/string/CyclicString.h @@ -31,6 +31,7 @@ public: explicit CyclicString(std::set<alphabet::Symbol>&& alphabet, std::vector<alphabet::Symbol>&& data); explicit CyclicString(const std::vector<alphabet::Symbol>& data); explicit CyclicString(std::vector<alphabet::Symbol>&& data); + explicit CyclicString(const std::string& str); virtual StringBase* clone() const; virtual StringBase* plunder() &&; diff --git a/alib2data/src/string/LinearString.cpp b/alib2data/src/string/LinearString.cpp index 4c875addc9b2f674da2c4dbd271aa3ad8f2450dd..71daea259d62959293eff4952514a28a479cc81e 100644 --- a/alib2data/src/string/LinearString.cpp +++ b/alib2data/src/string/LinearString.cpp @@ -7,6 +7,9 @@ #include "LinearString.h" #include "../exception/AlibException.h" +#include "../label/Label.h" +#include "../label/CharacterLabel.h" +#include "../alphabet/LabeledSymbol.h" #include <cassert> #include <sstream> @@ -43,6 +46,14 @@ LinearString::LinearString(std::vector<alphabet::Symbol>&& data) { m_Data = std::move(data); } +LinearString::LinearString(const std::string& str) { + for (unsigned i = 0; i < str.length(); ++i) + { + m_Data.push_back(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::CharacterLabel(str[i]))))); + } + alphabet = std::set<alphabet::Symbol>(m_Data.begin(), m_Data.end()); +} + StringBase* LinearString::clone() const { return new LinearString(*this); } diff --git a/alib2data/src/string/LinearString.h b/alib2data/src/string/LinearString.h index 875ca997a2a74b7e87b7ccc6e6f655550ca3cd32..53580f6279ddc0fde14c61ea01b2bfb67c405fa9 100644 --- a/alib2data/src/string/LinearString.h +++ b/alib2data/src/string/LinearString.h @@ -32,6 +32,7 @@ public: explicit LinearString(std::set<alphabet::Symbol>&& alphabet, std::vector<alphabet::Symbol>&& data); explicit LinearString(const std::vector<alphabet::Symbol>& data); explicit LinearString(std::vector<alphabet::Symbol>&& data); + explicit LinearString(const std::string& str); virtual StringBase* clone() const; virtual StringBase* plunder() &&; diff --git a/alib2data/src/string/StringBase.h b/alib2data/src/string/StringBase.h index 2ac457525e1a95b6d5018142c2b83bf9fa403787..64ef5419e6d3b03b6cfe014901241ac784d9157f 100644 --- a/alib2data/src/string/StringBase.h +++ b/alib2data/src/string/StringBase.h @@ -27,7 +27,7 @@ public: virtual StringBase* clone() const = 0; virtual StringBase* plunder() && = 0; - + }; } /* namespace string */ diff --git a/alib2data/src/string/common/StringAlphabet.cpp b/alib2data/src/string/common/StringAlphabet.cpp index 4b81ba221bb35d5d1ac209a591b78b8bdad4d24c..22c34a2203a047422bcd5904890675a2cb7fe62b 100644 --- a/alib2data/src/string/common/StringAlphabet.cpp +++ b/alib2data/src/string/common/StringAlphabet.cpp @@ -19,6 +19,12 @@ bool StringAlphabet::addSymbolToAlphabet(const alphabet::Symbol& symbol) { return alphabet.insert(symbol).second; } +void StringAlphabet::addSymbolsToAlphabet(const std::set<alphabet::Symbol>& symbols) { + for(const alphabet::Symbol& addedSymbol : symbols) { + addSymbolToAlphabet(addedSymbol); + } +} + void StringAlphabet::setAlphabet(const 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())); diff --git a/alib2data/src/string/common/StringAlphabet.h b/alib2data/src/string/common/StringAlphabet.h index a4c0365d6501d309149f2fbaf10321a993bee9cd..5838ed4608606773531ec5c0834aadd7e2e876fb 100644 --- a/alib2data/src/string/common/StringAlphabet.h +++ b/alib2data/src/string/common/StringAlphabet.h @@ -24,14 +24,18 @@ public: /** * Adds input symbol to input alphabet. * @param symbol Symbol to add - * @throws AutomatonException when symbol already exists */ bool addSymbolToAlphabet(const 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 - * @throws AutomatonException when symbol already exists */ void setAlphabet(const std::set<alphabet::Symbol>& symbols);