From dc979e7c5a0b9393165de47da8564a8c2d208eb6 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Wed, 21 Dec 2016 20:13:41 +0100 Subject: [PATCH] fix finding least lexicographical rotation --- .../src/string/simplify/NormalizeRotation.cpp | 19 +++++++++---------- .../test-src/string/compare/compareTest.cpp | 7 ++++++- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/alib2algo/src/string/simplify/NormalizeRotation.cpp b/alib2algo/src/string/simplify/NormalizeRotation.cpp index a2d3adc831..b8b9c35043 100644 --- a/alib2algo/src/string/simplify/NormalizeRotation.cpp +++ b/alib2algo/src/string/simplify/NormalizeRotation.cpp @@ -19,24 +19,23 @@ string::String NormalizeRotation::normalize(const string::String& string) { string::CyclicString < > NormalizeRotation::normalize(const string::CyclicString < >& string) { /** - * Lexicographically least circular substrings + * Lexicographically least circular substrings, + * based on * Kellogg S. Booth - * 1979 + * 1979, + * modified to working code by Ladislav Vagner */ const std::vector<alphabet::Symbol>& data = string.getContent(); - int* f = new int[data.size() + 1]; /** Knuth–Morris–Pratt like array */ + int* f = new int[ 2 * data.size() ]; /** Knuth–Morris–Pratt like array */ int k = 0; /** Least circular string shift value */ - int i; f[0] = -1; for (unsigned j = 1; j < 2 * data.size(); ++j) { - /** condition adjusted by Radomir Polach, >= is not correct */ - if (j - k > data.size()) break; - i = f[j - k - 1]; - while (data[j % data.size()] != data[(k + i + 1) % data.size()] && i != -1) { + int i = f[j - k - 1]; + while ( i != -1 && data[j % data.size()] != data[(k + i + 1) % data.size()]) { if (data[j % data.size()] < data[(k + i + 1) % data.size()]) k = j - i - 1; i = f[i]; } - if (data[j % data.size()] != data[(k + i + 1) % data.size()] && i == -1) { + if (i == -1 && data[j % data.size()] != data[k % data.size()]) { if (data[j % data.size()] < data[(k + i + 1) % data.size()]) k = j; f[j - k] = -1; } else f[j - k] = i + 1; @@ -47,7 +46,7 @@ string::CyclicString < > NormalizeRotation::normalize(const string::CyclicString return string; std::vector<alphabet::Symbol> rotated; - for (unsigned l = k; l < data.size() + k; ++l) { + for (unsigned l = k % data.size ( ); l < data.size() + k % data.size ( ); ++l) { rotated.push_back(data[l % data.size()]); } diff --git a/alib2algo/test-src/string/compare/compareTest.cpp b/alib2algo/test-src/string/compare/compareTest.cpp index 2606492375..b380ec5a43 100644 --- a/alib2algo/test-src/string/compare/compareTest.cpp +++ b/alib2algo/test-src/string/compare/compareTest.cpp @@ -56,7 +56,7 @@ void compareTest::testCompareCyclic() { string::CyclicString < > cyclic3n = string::simplify::NormalizeRotation::normalize(cyclic3); string::CyclicString < > cyclic4n = string::simplify::NormalizeRotation::normalize(cyclic4); - + CPPUNIT_ASSERT(cyclic1 == cyclic1n); CPPUNIT_ASSERT(cyclic1n == cyclic2n); CPPUNIT_ASSERT(cyclic1n == cyclic3n); CPPUNIT_ASSERT(cyclic2n == cyclic3n); @@ -64,5 +64,10 @@ void compareTest::testCompareCyclic() { CPPUNIT_ASSERT(cyclic4n != cyclic1n); CPPUNIT_ASSERT(cyclic4n != cyclic2n); CPPUNIT_ASSERT(cyclic4n != cyclic3n); + + string::CyclicString < > cyclic5({alphabet::Symbol(62), alphabet::Symbol(62), alphabet::Symbol(100), alphabet::Symbol(62)}); + string::CyclicString < > cyclic5n = string::simplify::NormalizeRotation::normalize(cyclic5); + string::CyclicString < > cyclic5r({alphabet::Symbol(62), alphabet::Symbol(62), alphabet::Symbol(62), alphabet::Symbol(100)}); + CPPUNIT_ASSERT(cyclic5n == cyclic5r); } -- GitLab