From c95c98764a9f2a469da7367c1eac54ffbe9312b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ing=2E=20Radom=C3=ADr=20Pol=C3=A1ch?= <polacrad@fit.cvut.cz> Date: Sun, 14 Sep 2014 22:44:47 +0200 Subject: [PATCH] FEATURE: cylcic string comparison --- .../compare/string/CyclicStringCompare.cpp | 41 +++++++++++++++++++ .../src/compare/string/CyclicStringCompare.h | 24 +++++++++++ alib2algo/test-src/compare/compareTest.cpp | 33 +++++++++++++++ alib2algo/test-src/compare/compareTest.h | 21 ++++++++++ alib2data/src/string/CyclicString.cpp | 11 +++++ alib2data/src/string/CyclicString.h | 1 + alib2data/src/string/LinearString.cpp | 11 +++++ alib2data/src/string/LinearString.h | 1 + alib2data/src/string/StringBase.h | 2 +- .../src/string/common/StringAlphabet.cpp | 6 +++ alib2data/src/string/common/StringAlphabet.h | 8 +++- 11 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 alib2algo/src/compare/string/CyclicStringCompare.cpp create mode 100644 alib2algo/src/compare/string/CyclicStringCompare.h create mode 100644 alib2algo/test-src/compare/compareTest.cpp create mode 100644 alib2algo/test-src/compare/compareTest.h diff --git a/alib2algo/src/compare/string/CyclicStringCompare.cpp b/alib2algo/src/compare/string/CyclicStringCompare.cpp new file mode 100644 index 0000000000..9c15baa629 --- /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 0000000000..5b8cb14518 --- /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 0000000000..9ada8b24b7 --- /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 0000000000..9238a15e2b --- /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 fcf1fc8e58..a0903dca5b 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 c1b4aef344..7173b9790d 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 4c875addc9..71daea259d 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 875ca997a2..53580f6279 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 2ac457525e..64ef5419e6 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 4b81ba221b..22c34a2203 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 a4c0365d65..5838ed4608 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); -- GitLab