Skip to content
Snippets Groups Projects
Commit efa5497c authored by Ing. Radomír Polách's avatar Ing. Radomír Polách
Browse files

FEATURE: cyclic string canonical form in O(n) time and O(n) space

parent 5ad64757
No related branches found
No related tags found
No related merge requests found
......@@ -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))
......
......@@ -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 {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment