diff --git a/alib2data/makefile b/alib2data/makefile index 57af86af635cbc30c1e1c67a2f2635f114b7e135..f138e3cb545bebf552e6b1e72cca6c9cc262ff99 100644 --- a/alib2data/makefile +++ b/alib2data/makefile @@ -2,7 +2,7 @@ SHELL:=/bin/bash LIBRARY:=libalib2data.so TESTBIN:=alib2test -LDFLAGS:= /usr/lib64/libbfd.a /usr/lib64/libiberty.a -lz -ldl -rdynamic -shared -lxml2 +LDFLAGS:=-lbfd -liberty -lz -ldl -rdynamic -shared -lxml2 TEST_LDFLAGS:= -L../alib2data/lib -rdynamic -lxml2 -lalib2data -lcppunit -Wl,-rpath,. OBJECTS:=$(patsubst src/%.cpp, obj/%.o, $(shell find src/ -name *cpp)) diff --git a/alib2data/src/string/CyclicString.cpp b/alib2data/src/string/CyclicString.cpp index dccd4fad7f43872c73391cf1398462bfd7a21a64..fcf1fc8e582763619901c6b5e45df492b7e793fd 100644 --- a/alib2data/src/string/CyclicString.cpp +++ b/alib2data/src/string/CyclicString.cpp @@ -83,13 +83,40 @@ void CyclicString::setContent(std::vector<alphabet::Symbol> data) { if(unknownSymbols.size() > 0) throw exception::AlibException("Input symbols not in the alphabet."); - m_Data = data; - for(unsigned i = 1; i < data.size(); i++) { - data.push_back(std::move(data[0])); - data.erase(data.begin()); - - if(m_Data > data) m_Data = data; - } + /** + * Lexicographically least circular substrings + * Kellogg S. Booth + * 1979 + */ + int* f = new int[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 RadomĂr Polách, >= 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) { + 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 (data[j % data.size()] < data[(k + i + 1) % data.size()]) k = j; + f[j - k] = -1; + } else f[j - k] = i+1; + } + delete [] f; + + if (k == 0) { + m_Data = data; + return; + } + + std::vector<alphabet::Symbol> tmp; + for (unsigned l = k; l < data.size() + k; ++l) { + tmp.push_back(std::move(data[l % data.size()])); + } + m_Data = tmp; } bool CyclicString::isEmpty() const {