Skip to content
Snippets Groups Projects
Commit 0c3a03ec authored by Tomáš Pecka's avatar Tomáš Pecka Committed by Jan Trávníček
Browse files

algo: stringology: Border Array

parent f4399d3a
No related branches found
No related tags found
No related merge requests found
/*
* BorderArray.cpp
*
* Created on: 1. 11. 2014
* Author: Tomas Pecka
*/
#include "BorderArray.h"
#include <container/ObjectsVector.h>
#include <container/ObjectsPair.h>
#include <exception/AlibException.h>
#include <object/Object.h>
#include <primitive/Integer.h>
#include <string/LinearString.h>
namespace stringology {
namespace exact {
std::vector<unsigned> BorderArray::construct(const string::String& string) {
std::vector<unsigned> out;
string.getData().Accept((void*) &out, BorderArray::BORDER_ARRAY);
return out;
}
std::vector<unsigned> BorderArray::construct(const string::LinearString& string) {
const auto& w = string.getContent();
std::vector<unsigned> res(w.size() + 1);
res[0] = 0;
res[1] = 0;
for(size_t i = 1; i < w.size(); i++) {
unsigned b = res[i];
while (b > 0 && w[i + 1 - 1] != w[b + 1 - 1])
b = res[b];
if(w[i + 1 - 1] == w[b + 1 - 1])
res[i + 1] = b + 1;
else
res[i + 1] = 0;
}
return res;
}
void BorderArray::Visit(void* data, const string::LinearString& string) const {
std::vector<unsigned> & out = *(std::vector<unsigned>*) data;
out = this->construct(string);
}
void BorderArray::Visit(void*, const string::Epsilon&) const {
throw exception::AlibException("Unsupported string type Epsilon");
}
void BorderArray::Visit(void*, const string::CyclicString&) const {
throw exception::AlibException("Unsupported string type CyclicString");
}
const BorderArray BorderArray::BORDER_ARRAY;
} /* namespace exact */
} /* namespace stringology */
/*
* BorderArray.h
*
* Created on: 1. 11. 2014
* Author: Tomas Pecka
*/
#ifndef _BORDER_ARRAY_H_
#define _BORDER_ARRAY_H_
#include <vector>
#include <string/String.h>
namespace stringology {
namespace exact {
class BorderArray : public string::VisitableStringBase::const_visitor_type {
public:
/**
* Computes border array of string
* @param string string to compute border array for
* @return Vector of length same as string, where i-th index corresponds to i-th element of string
*/
static std::vector<unsigned> construct(const string::String& string);
static std::vector<unsigned> construct(const string::LinearString& string);
private:
void Visit(void*, const string::Epsilon& pattern) const;
void Visit(void*, const string::LinearString& pattern) const;
void Visit(void*, const string::CyclicString& pattern) const;
static const BorderArray BORDER_ARRAY;
};
} /* namespace exact */
} /* namespace stringology */
#endif /* _BORDER_ARRAY_H_ */
#include "borderArrayTest.h"
#include "string/String.h"
#include "stringology/exact/BorderArray.h"
#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
CPPUNIT_TEST_SUITE_REGISTRATION( borderArrayTest );
void borderArrayTest::setUp() {
}
void borderArrayTest::tearDown() {
}
void borderArrayTest::testBorderArray() {
string::String string = string::stringFrom("alfalfaalf");
std::vector<unsigned> borderArray = stringology::exact::BorderArray::construct(string);
std::vector<unsigned> expected {0, 0, 0, 0, 1, 2, 3, 1, 1, 2, 3};
CPPUNIT_ASSERT(borderArray != expected);
}
#ifndef BORDER_ARRAY_TEST
#define BORDER_ARRAY_TEST
#include <cppunit/extensions/HelperMacros.h>
class borderArrayTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( borderArrayTest );
CPPUNIT_TEST( testBorderArray );
CPPUNIT_TEST_SUITE_END();
public:
void setUp();
void tearDown();
void testBorderArray();
};
#endif // BORDER_ARRAY_TEST
......@@ -11,11 +11,11 @@
 
namespace string {
 
string::String symbolFrom( const alphabet::Symbol& symbol ) {
string::String stringFrom( const alphabet::Symbol& symbol ) {
return string::String { string::LinearString { std::vector<alphabet::Symbol> { symbol } } };
}
 
string::String symbolFrom( const std::string& string ) {
string::String stringFrom( const std::string& string ) {
return string::String { string::LinearString { string } };
}
 
......
......@@ -12,8 +12,11 @@
#include <exception/AlibException.h>
#include <string/String.h>
#include <automaton/Automaton.h>
#include <container/Container.h>
#include <string/naive/ExactMatch.h>
#include <stringology/exact/ExactMatchingAutomaton.h>
#include <stringology/exact/BorderArray.h>
 
int main(int argc, char* argv[]) {
try {
......@@ -22,6 +25,7 @@ int main(int argc, char* argv[]) {
std::vector<std::string> allowed;
allowed.push_back("exactMatchingAutomaton");
allowed.push_back("exactMatch");
allowed.push_back("borderArray");
TCLAP::ValuesConstraint<std::string> allowedVals( allowed );
 
TCLAP::ValueArg<std::string> algorithm( "a", "algorithm", "Execute algorithm", false, "exactMatch", &allowedVals);
......@@ -31,7 +35,7 @@ int main(int argc, char* argv[]) {
cmd.add( subject );
 
TCLAP::ValueArg<std::string> pattern( "p", "pattern", "Pattern string from file", false, "-", "file");
cmd.add( pattern );
cmd.add( pattern );
 
cmd.parse(argc,argv);
 
......@@ -68,6 +72,11 @@ int main(int argc, char* argv[]) {
automaton::Automaton automaton = stringology::exact::ExactMatchingAutomaton::construct(pattern);
alib::XmlDataFactory::toStdout(automaton);
return 0;
} else if( algorithm.getValue() == "borderArray") {
string::String subject = alib::XmlDataFactory::fromTokens<string::String>(subjectTokens);
std::vector<unsigned> borderArray = stringology::exact::BorderArray::construct(subject);
alib::XmlDataFactory::toStdout(borderArray);
return 0;
} else {
throw exception::AlibException( "Invalid algorithm" );
return 1;
......
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