From 8c3c1c5d6eb7c7b70586ae53def8eb240f3a8fcc Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Thu, 20 Dec 2018 22:08:45 +0100
Subject: [PATCH] LZ77

---
 alib2algo/src/string/compress/LZ77.cpp        |  22 ----
 alib2algo/src/string/compress/LZ77.h          | 103 ----------------
 .../src/string/compress/LZ77Decompress.cpp    |  22 ----
 .../src/string/compress/LZ77Decompress.h      |  67 -----------
 .../compression/ArithmeticCompression.cpp     |   9 ++
 .../compression/ArithmeticDecompression.cpp   |   9 ++
 .../compression/LZ77Compression.cpp           |  15 +++
 .../stringology/compression/LZ77Compression.h |  95 +++++++++++++++
 .../compression/LZ77Decompression.cpp         |  15 +++
 .../compression/LZ77Decompression.h           |  49 ++++++++
 .../string/compress/LZ77DecompressTest.cpp    |  71 -----------
 .../string/compress/LZ77DecompressTest.h      |  22 ----
 .../test-src/string/compress/LZ77Test.cpp     |  56 ---------
 .../stringology/compression/LZ77Test.cpp      | 111 ++++++++++++++++++
 .../compression}/LZ77Test.h                   |   9 +-
 15 files changed, 311 insertions(+), 364 deletions(-)
 delete mode 100644 alib2algo/src/string/compress/LZ77.cpp
 delete mode 100644 alib2algo/src/string/compress/LZ77.h
 delete mode 100644 alib2algo/src/string/compress/LZ77Decompress.cpp
 delete mode 100644 alib2algo/src/string/compress/LZ77Decompress.h
 create mode 100644 alib2algo/src/stringology/compression/ArithmeticCompression.cpp
 create mode 100644 alib2algo/src/stringology/compression/ArithmeticDecompression.cpp
 create mode 100644 alib2algo/src/stringology/compression/LZ77Compression.cpp
 create mode 100644 alib2algo/src/stringology/compression/LZ77Compression.h
 create mode 100644 alib2algo/src/stringology/compression/LZ77Decompression.cpp
 create mode 100644 alib2algo/src/stringology/compression/LZ77Decompression.h
 delete mode 100644 alib2algo/test-src/string/compress/LZ77DecompressTest.cpp
 delete mode 100644 alib2algo/test-src/string/compress/LZ77DecompressTest.h
 delete mode 100644 alib2algo/test-src/string/compress/LZ77Test.cpp
 create mode 100644 alib2algo/test-src/stringology/compression/LZ77Test.cpp
 rename alib2algo/test-src/{string/compress => stringology/compression}/LZ77Test.h (60%)

diff --git a/alib2algo/src/string/compress/LZ77.cpp b/alib2algo/src/string/compress/LZ77.cpp
deleted file mode 100644
index 9a75bfc58f..0000000000
--- a/alib2algo/src/string/compress/LZ77.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * LZ77.cpp
- *
- *  Created on: 1. 3. 2017
- *      Author: Jan Parma
- */
-
-#include "LZ77.h"
-
-namespace string {
-
-namespace compress {
-
-std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > > LZ77::compress ( const string::String & string, unsigned int searchBufferSize, unsigned int lookaheadBufferSize ) {
-	return dispatch ( string.getData ( ), searchBufferSize, lookaheadBufferSize );
-}
-
-auto LZ77Compress = LZ77::RegistratorWrapper < std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > >, string::LinearString < > > ( LZ77::compress );
-
-} /* namespace compress */
-
-} /* namespace string */
diff --git a/alib2algo/src/string/compress/LZ77.h b/alib2algo/src/string/compress/LZ77.h
deleted file mode 100644
index 26970c048d..0000000000
--- a/alib2algo/src/string/compress/LZ77.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * LZ77.h
- *
- *  Created on: 1. 3. 2017
- *      Author: Jan Parma
- */
-
-#ifndef _LZ77_H_
-#define _LZ77_H_
-
-#include <core/multipleDispatch.hpp>
-#include <string/StringFeatures.h>
-#include <tuple>
-#include <vector>
-
-#include <string/LinearString.h>
-#include <string/String.h>
-
-#include <exception/CommonException.h>
-
-namespace string {
-
-namespace compress {
-
-class LZ77 : public std::SingleDispatch < LZ77, std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > >, const string::StringBase &, unsigned int, unsigned int > {
-public:
-	static std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > > compress ( const string::String & string, unsigned int searchBufferSize, unsigned int lookaheadBufferSize );
-
-	template < class SymbolType >
-	static std::vector < std::tuple < unsigned int, unsigned int, SymbolType > > compress ( const string::LinearString < SymbolType > & string, unsigned int searchBufferSize, unsigned int lookaheadBufferSize );
-
-private:
-	template < class SymbolType >
-	static int equal ( const string::LinearString < SymbolType > & string, unsigned int first1, unsigned int last1, unsigned int first2 );
-};
-
-// Main method that handle compress
-template < class SymbolType >
-std::vector < std::tuple < unsigned int, unsigned int, SymbolType > > LZ77::compress ( const string::LinearString < SymbolType > & string, unsigned int searchBufferSize, unsigned int lookaheadBufferSize ) {
-
-	if(searchBufferSize == 0)
-		throw exception::CommonException("LZ77: search buffer size must be greater than 0");
-
-	if(lookaheadBufferSize == 0)
-		throw exception::CommonException("LZ77: lookahead buffer size must be greater than 0");
-
-
-	size_t pointer = 0;
-	unsigned int match = 0;
-	unsigned int maxMatch = 0;
-	unsigned int sbPointer = 0;
-
-	std::vector < std::tuple < unsigned int, unsigned int, SymbolType > > output;
-
-	while ( pointer < string.getContent ( ).size ( ) ) {
-		if ( pointer + lookaheadBufferSize >= string.getContent ( ).size ( ) )
-			lookaheadBufferSize = string.getContent ( ).size ( ) - pointer - 1;
-
-		for ( int j = pointer - 1; j > ( int ) pointer - 1 - ( int ) searchBufferSize; j-- ) {
-			if ( j < 0 ) break;
-
-			match = equal ( string, pointer, pointer + lookaheadBufferSize - 1, j );
-
-			if ( maxMatch < match ) {
-				maxMatch = match;
-				sbPointer = j;
-			}
-		}
-
-		std::tuple < unsigned int, unsigned int, SymbolType > triple ( maxMatch == 0 ? 0 : pointer - sbPointer, maxMatch, string.getContent ( )[pointer + maxMatch] );
-		output.push_back ( triple );
-
-		pointer = pointer + maxMatch + 1;
-
-		maxMatch = 0;
-	}
-
-	return output;
-}
-
-// Method that return longest match of two substrings that are defined as incoming string and index of first staring letter
-template < class SymbolType >
-int LZ77::equal ( const string::LinearString < SymbolType > & string, unsigned int first1, unsigned int last1, unsigned int first2 ) {
-
-	int steps = 0;
-
-	while ( first1 <= last1 ) {
-		if ( string.getContent ( )[first1] != string.getContent ( )[first2] )
-			return steps;
-
-		first1++;
-		first2++;
-		steps++;
-	}
-
-	return steps;
-}
-
-} /* namespace compress */
-
-} /* namespace string */
-
-#endif /* _LZ77_H_ */
diff --git a/alib2algo/src/string/compress/LZ77Decompress.cpp b/alib2algo/src/string/compress/LZ77Decompress.cpp
deleted file mode 100644
index 7de478f01f..0000000000
--- a/alib2algo/src/string/compress/LZ77Decompress.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * LZ77Decompress.cpp
- *
- *  Created on: 1. 3. 2017
- *      Author: Jan Parma
- */
-
-#include "LZ77Decompress.h"
-
-namespace string {
-
-namespace compress {
-
-string::String LZ77Decompress::decompress ( const std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > > & input ) {
-	return dispatch ( input );
-}
-
-auto LZ77Decompress = LZ77Decompress::RegistratorWrapper < string::LinearString < >, std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > > > ( LZ77Decompress::decompress );
-
-} /* namespace compress */
-
-} /* namespace string */
diff --git a/alib2algo/src/string/compress/LZ77Decompress.h b/alib2algo/src/string/compress/LZ77Decompress.h
deleted file mode 100644
index 598c12a108..0000000000
--- a/alib2algo/src/string/compress/LZ77Decompress.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * LZ77Decompress.h
- *
- *  Created on: 1. 3. 2017
- *      Author: Jan Parma
- */
-
-#ifndef _LZ77DECOMPRESS_H_
-#define _LZ77DECOMPRESS_H_
-
-#define SEARCH_BUFFER_LENGTH	   6
-#define LOOKAHEAD_BUFFER_LENGTH	   4
-
-#include <core/multipleDispatch.hpp>
-#include <string/StringFeatures.h>
-#include <tuple>
-#include <vector>
-
-#include <string/LinearString.h>
-#include <string/String.h>
-
-namespace string {
-
-namespace compress {
-
-class LZ77Decompress : public std::SingleDispatch < LZ77Decompress, string::String, const std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > > & > {
-public:
-	static string::String decompress ( const std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > > & input );
-
-	template < class SymbolType >
-	static string::LinearString < SymbolType > decompress ( const std::vector < std::tuple < unsigned int, unsigned int, SymbolType > > & input );
-};
-
-// Main method that handle decompress
-template < class SymbolType >
-string::LinearString < SymbolType > LZ77Decompress::decompress ( const std::vector < std::tuple < unsigned int, unsigned int, SymbolType > > & input ) {
-
-	string::LinearString < SymbolType > output;
-
-	for ( unsigned int i = 0; i < input.size ( ); i++ )
-	{
-		if ( ( std::get < 0 > ( input[i] ) == 0 ) && ( std::get < 1 > ( input[i] ) == 0 ) )
-		{
-			output.extendAlphabet ( std::set < SymbolType > { std::get < 2 > ( input[i] ) } );
-			output.appendSymbol ( std::get < 2 > ( input[i] ) );
-		} 
-		else 
-		{
-			for ( unsigned int j = 0; j < std::get < 1 > ( input[i] ); j++ )
-			{
-				output.extendAlphabet ( std::set < SymbolType > { output.getContent ( )[output.getContent ( ).size ( ) - std::get < 0 > ( input[i] )] } );
-				output.appendSymbol ( output.getContent ( )[output.getContent ( ).size ( ) - std::get < 0 > ( input[i] )] );
-			}
-
-			output.extendAlphabet ( std::set < SymbolType > { std::get < 2 > ( input[i] ) } );
-			output.appendSymbol ( std::get < 2 > ( input[i] ) );
-		}
-	}
-
-	return output;
-}
-
-} /* namespace compress */
-
-} /* namespace string */
-
-#endif /* _LZ77DECOMPRESS_H_ */
diff --git a/alib2algo/src/stringology/compression/ArithmeticCompression.cpp b/alib2algo/src/stringology/compression/ArithmeticCompression.cpp
new file mode 100644
index 0000000000..2ba0709a6f
--- /dev/null
+++ b/alib2algo/src/stringology/compression/ArithmeticCompression.cpp
@@ -0,0 +1,9 @@
+#include "ArithmeticCompression.h"
+#include <registration/AlgoRegistration.hpp>
+
+namespace {
+
+auto ArithmeticCompression = registration::AbstractRegister < stringology::compression::AdaptiveIntegerArithmeticCompression, ext::vector < bool >, const string::LinearString < > & > ( stringology::compression::AdaptiveIntegerArithmeticCompression::compress );
+
+} /* namespace */
+
diff --git a/alib2algo/src/stringology/compression/ArithmeticDecompression.cpp b/alib2algo/src/stringology/compression/ArithmeticDecompression.cpp
new file mode 100644
index 0000000000..a3fcb4a02b
--- /dev/null
+++ b/alib2algo/src/stringology/compression/ArithmeticDecompression.cpp
@@ -0,0 +1,9 @@
+#include "ArithmeticDecompression.h"
+#include <registration/AlgoRegistration.hpp>
+
+namespace {
+
+auto ArithmeticDecompression = registration::AbstractRegister < stringology::compression::AdaptiveIntegerArithmeticDecompression, string::LinearString < >, const ext::vector < bool > &, const ext::set < object::Object > &  > ( stringology::compression::AdaptiveIntegerArithmeticDecompression::decompress );
+
+} /* namespace */
+
diff --git a/alib2algo/src/stringology/compression/LZ77Compression.cpp b/alib2algo/src/stringology/compression/LZ77Compression.cpp
new file mode 100644
index 0000000000..eb7fc9c7bd
--- /dev/null
+++ b/alib2algo/src/stringology/compression/LZ77Compression.cpp
@@ -0,0 +1,15 @@
+/*
+ * LZ77.cpp
+ *
+ *  Created on: 1. 3. 2017
+ *      Author: Jan Parma
+ */
+
+#include "LZ77Compression.h"
+#include <registration/AlgoRegistration.hpp>
+
+namespace {
+
+auto LZ77CompressionLinearString = registration::AbstractRegister < stringology::compression::LZ77Compression, std::vector < std::tuple < unsigned, unsigned, DefaultSymbolType > >, const string::LinearString < > &, unsigned, unsigned > ( stringology::compression::LZ77Compression::compress );
+
+} /* namespace */
diff --git a/alib2algo/src/stringology/compression/LZ77Compression.h b/alib2algo/src/stringology/compression/LZ77Compression.h
new file mode 100644
index 0000000000..53408526fb
--- /dev/null
+++ b/alib2algo/src/stringology/compression/LZ77Compression.h
@@ -0,0 +1,95 @@
+/*
+ * LZ77.h
+ *
+ *  Created on: 1. 3. 2017
+ *      Author: Jan Parma
+ */
+
+#ifndef _LZ77_H_
+#define _LZ77_H_
+
+#include <tuple>
+#include <vector>
+
+#include <string/LinearString.h>
+
+#include <exception/CommonException.h>
+
+namespace stringology {
+
+namespace compression {
+
+class LZ77Compression {
+public:
+	template < class SymbolType >
+	static std::vector < std::tuple < unsigned, unsigned, SymbolType > > compress ( const string::LinearString < SymbolType > & string, unsigned searchBufferSize, unsigned lookaheadBufferSize );
+
+private:
+	template < class SymbolType >
+	static int equal ( const string::LinearString < SymbolType > & string, unsigned first1, unsigned last1, unsigned first2 );
+};
+
+// Main method that handle compress
+template < class SymbolType >
+std::vector < std::tuple < unsigned, unsigned, SymbolType > > LZ77Compression::compress ( const string::LinearString < SymbolType > & string, unsigned searchBufferSize, unsigned lookaheadBufferSize ) {
+
+	if(searchBufferSize == 0)
+		throw exception::CommonException("LZ77: search buffer size must be greater than 0");
+
+	if(lookaheadBufferSize == 0)
+		throw exception::CommonException("LZ77: lookahead buffer size must be greater than 0");
+
+	size_t pointer = 0;
+
+	std::vector < std::tuple < unsigned, unsigned, SymbolType > > output;
+
+	while ( pointer < string.getContent ( ).size ( ) ) {
+		unsigned lookaheadBufferRealSize = lookaheadBufferSize;
+		if ( pointer + lookaheadBufferSize + 1 > string.getContent ( ).size ( ) )
+			lookaheadBufferRealSize = string.getContent ( ).size ( ) - pointer - 1;
+
+		unsigned searchBufferRealSize = searchBufferSize;
+		if ( pointer < searchBufferSize )
+			searchBufferRealSize = pointer;
+
+		unsigned maxMatch = 0;
+		unsigned sbPointer = pointer;
+		for ( unsigned j = pointer - searchBufferRealSize; j < pointer; j ++ ) {
+			unsigned match = equal ( string, pointer, pointer + lookaheadBufferRealSize, j );
+
+			if ( maxMatch <= match ) {
+				maxMatch = match;
+				sbPointer = j;
+			}
+		}
+
+		output.push_back ( std::tuple < unsigned, unsigned, SymbolType > ( pointer - sbPointer, maxMatch, string.getContent ( ) [ pointer + maxMatch ] ) );
+		pointer = pointer + maxMatch + 1;
+	}
+
+	return output;
+}
+
+// Method that return longest match of two substrings that are defined as incoming string and index of first staring letter
+template < class SymbolType >
+int LZ77Compression::equal ( const string::LinearString < SymbolType > & string, unsigned first1, unsigned last1, unsigned first2 ) {
+
+	int steps = 0;
+
+	while ( first1 < last1 ) {
+		if ( string.getContent ( )[first1] != string.getContent ( )[first2] )
+			return steps;
+
+		first1++;
+		first2++;
+		steps++;
+	}
+
+	return steps;
+}
+
+} /* namespace compression */
+
+} /* namespace stringology */
+
+#endif /* _LZ77_H_ */
diff --git a/alib2algo/src/stringology/compression/LZ77Decompression.cpp b/alib2algo/src/stringology/compression/LZ77Decompression.cpp
new file mode 100644
index 0000000000..8b9fad34d5
--- /dev/null
+++ b/alib2algo/src/stringology/compression/LZ77Decompression.cpp
@@ -0,0 +1,15 @@
+/*
+ * LZ77Decompression.cpp
+ *
+ *  Created on: 1. 3. 2017
+ *      Author: Jan Parma
+ */
+
+#include "LZ77Decompression.h"
+#include <registration/AlgoRegistration.hpp>
+
+namespace {
+
+auto LZ77Decompression = registration::AbstractRegister < stringology::compression::LZ77Decompression, string::LinearString < >, const std::vector < std::tuple < unsigned, unsigned, DefaultSymbolType > > & > ( stringology::compression::LZ77Decompression::decompress );
+
+} /* namespace */
diff --git a/alib2algo/src/stringology/compression/LZ77Decompression.h b/alib2algo/src/stringology/compression/LZ77Decompression.h
new file mode 100644
index 0000000000..6f69870d00
--- /dev/null
+++ b/alib2algo/src/stringology/compression/LZ77Decompression.h
@@ -0,0 +1,49 @@
+/*
+ * LZ77Decompression.h
+ *
+ *  Created on: 1. 3. 2017
+ *      Author: Jan Parma
+ */
+
+#ifndef _LZ77DECOMPRESS_H_
+#define _LZ77DECOMPRESS_H_
+
+#include <tuple>
+#include <vector>
+#include <alib/set>
+
+#include <string/LinearString.h>
+
+namespace stringology {
+
+namespace compression {
+
+class LZ77Decompression {
+public:
+	template < class SymbolType >
+	static string::LinearString < SymbolType > decompress ( const std::vector < std::tuple < unsigned, unsigned, SymbolType > > & input );
+};
+
+// Main method that handle decompress
+template < class SymbolType >
+string::LinearString < SymbolType > LZ77Decompression::decompress ( const std::vector < std::tuple < unsigned, unsigned, SymbolType > > & input ) {
+
+	string::LinearString < SymbolType > output;
+
+	for ( unsigned i = 0; i < input.size ( ); i++ ) {
+		for ( unsigned j = 0; j < std::get < 1 > ( input[i] ); j++ ) {
+			output.appendSymbol ( output.getContent ( )[output.getContent ( ).size ( ) - std::get < 0 > ( input[i] )] );
+		}
+
+		output.extendAlphabet ( ext::set < SymbolType > { std::get < 2 > ( input[i] ) } );
+		output.appendSymbol ( std::get < 2 > ( input[i] ) );
+	}
+
+	return output;
+}
+
+} /* namespace compression */
+
+} /* namespace stringology */
+
+#endif /* _LZ77DECOMPRESS_H_ */
diff --git a/alib2algo/test-src/string/compress/LZ77DecompressTest.cpp b/alib2algo/test-src/string/compress/LZ77DecompressTest.cpp
deleted file mode 100644
index f721ff262f..0000000000
--- a/alib2algo/test-src/string/compress/LZ77DecompressTest.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-#include "LZ77DecompressTest.h"
-
-#include <string/String.h>
-#include <string/compress/LZ77.h>
-#include <string/compress/LZ77Decompress.h>
-
-#define CPPUNIT_IMPLY( x, y )    CPPUNIT_ASSERT ( !( x ) || ( y ) )
-
-#include <iostream>
-#include <tuple>
-
-
-CPPUNIT_TEST_SUITE_NAMED_REGISTRATION ( LZ77DecompressTest, "stringology" );
-CPPUNIT_TEST_SUITE_REGISTRATION ( LZ77DecompressTest );
-
-void LZ77DecompressTest::setUp ( ) {
-}
-
-void LZ77DecompressTest::tearDown ( ) {
-}
-
-void LZ77DecompressTest::testLZ77Decompress1 ( ) {
-
-	std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > > input;
-
-	input.push_back(std::make_tuple(0, 0, DefaultSymbolType ( 'a' )));
-	input.push_back(std::make_tuple(1, 1, DefaultSymbolType ( 'b' )));
-	input.push_back(std::make_tuple(3, 2, DefaultSymbolType ( 'c' )));
-	input.push_back(std::make_tuple(3, 2, DefaultSymbolType ( 'a' )));
-	input.push_back(std::make_tuple(1, 3, DefaultSymbolType ( 'b' )));
-	input.push_back(std::make_tuple(2, 3, DefaultSymbolType ( 'b' )));
-
-	string::String res = string::compress::LZ77Decompress::decompress ( input );
-
-	std::string string = "aabaacaaaaaababab";
-	string::String expectedString = string::stringFrom ( string );
-
-	CPPUNIT_ASSERT ( res == expectedString );
-
-}
-
-void LZ77DecompressTest::testLZ77Decompress2 ( ) {
-
-	std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > > input;
-
-	input.push_back(std::make_tuple(0, 0, DefaultSymbolType ( 'a' )));
-	input.push_back(std::make_tuple(1, 1, DefaultSymbolType ( 'c' )));
-	input.push_back(std::make_tuple(3, 4, DefaultSymbolType ( 'b' )));
-	input.push_back(std::make_tuple(3, 3, DefaultSymbolType ( 'a' )));
-	input.push_back(std::make_tuple(1, 2, DefaultSymbolType ( 'c' )));
-
-	string::String res = string::compress::LZ77Decompress::decompress ( input );
-
-	std::string string = "aacaacabcabaaac";
-	string::String expectedString = string::stringFrom ( string );
-
-	CPPUNIT_ASSERT ( res == expectedString );
-
-}
-
-void LZ77DecompressTest::testLZ77Decompress3 ( ) {
-
-	std::string string = "";
-	string::String input = string::stringFrom ( string );
-
-	std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > > out = string::compress::LZ77::compress ( input, 6, 4 );
-
-	string::String res = string::compress::LZ77Decompress::decompress ( out );
-
-	CPPUNIT_ASSERT ( input == res );
-}
diff --git a/alib2algo/test-src/string/compress/LZ77DecompressTest.h b/alib2algo/test-src/string/compress/LZ77DecompressTest.h
deleted file mode 100644
index f4a3eecfe6..0000000000
--- a/alib2algo/test-src/string/compress/LZ77DecompressTest.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef LZ77DECOMPRESS_TEST
-#define LZ77DECOMPRESS_TEST
-
-#include <cppunit/extensions/HelperMacros.h>
-
-class LZ77DecompressTest : public CppUnit::TestFixture {
-	CPPUNIT_TEST_SUITE ( LZ77DecompressTest );
-	CPPUNIT_TEST ( testLZ77Decompress1 );
-	CPPUNIT_TEST ( testLZ77Decompress2 );
-	CPPUNIT_TEST ( testLZ77Decompress3 );
-	CPPUNIT_TEST_SUITE_END ( );
-
-public:
-	void setUp ( );
-	void tearDown ( );
-
-	void testLZ77Decompress1 ( );
-	void testLZ77Decompress2 ( );
-	void testLZ77Decompress3 ( );
-};
-
-#endif // LZ77DECOMPRESS_TEST
\ No newline at end of file
diff --git a/alib2algo/test-src/string/compress/LZ77Test.cpp b/alib2algo/test-src/string/compress/LZ77Test.cpp
deleted file mode 100644
index 88bec4d7f0..0000000000
--- a/alib2algo/test-src/string/compress/LZ77Test.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#include "LZ77Test.h"
-
-#include <string/String.h>
-#include <string/compress/LZ77.h>
-
-#define CPPUNIT_IMPLY( x, y )    CPPUNIT_ASSERT ( !( x ) || ( y ) )
-
-#include <iostream>
-#include <tuple>
-
-
-CPPUNIT_TEST_SUITE_NAMED_REGISTRATION ( LZ77Test, "stringology" );
-CPPUNIT_TEST_SUITE_REGISTRATION ( LZ77Test );
-
-void LZ77Test::setUp ( ) {
-}
-
-void LZ77Test::tearDown ( ) {
-}
-
-void LZ77Test::testLZ77_1 ( ) {
-	std::string testStr = "aabaacaaaaaababab";
-
-	string::String string = string::stringFrom ( testStr );
-	std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > > res = string::compress::LZ77::compress ( string, 6, 4 );
-
-	std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > > expectedOutput;
-
-	expectedOutput.push_back(std::make_tuple(0, 0, DefaultSymbolType ( 'a' )));
-	expectedOutput.push_back(std::make_tuple(1, 1, DefaultSymbolType ( 'b' )));
-	expectedOutput.push_back(std::make_tuple(3, 2, DefaultSymbolType ( 'c' )));
-	expectedOutput.push_back(std::make_tuple(3, 2, DefaultSymbolType ( 'a' )));
-	expectedOutput.push_back(std::make_tuple(1, 3, DefaultSymbolType ( 'b' )));
-	expectedOutput.push_back(std::make_tuple(2, 3, DefaultSymbolType ( 'b' )));
-
-	CPPUNIT_ASSERT ( res == expectedOutput );
-
-}
-
-void LZ77Test::testLZ77_2 ( ) {
-
-	std::string testStr = "aacaacabcabaaac";
-
-	string::String string = string::stringFrom ( testStr );
-	std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > > res = string::compress::LZ77::compress ( string, 6, 4 );
-
-	std::vector < std::tuple < unsigned int, unsigned int, DefaultSymbolType > > expectedOutput;
-
-	expectedOutput.push_back(std::make_tuple(0, 0, DefaultSymbolType ( 'a' )));
-	expectedOutput.push_back(std::make_tuple(1, 1, DefaultSymbolType ( 'c' )));
-	expectedOutput.push_back(std::make_tuple(3, 4, DefaultSymbolType ( 'b' )));
-	expectedOutput.push_back(std::make_tuple(3, 3, DefaultSymbolType ( 'a' )));
-	expectedOutput.push_back(std::make_tuple(1, 2, DefaultSymbolType ( 'c' )));
-
-	CPPUNIT_ASSERT ( res == expectedOutput );
-}
diff --git a/alib2algo/test-src/stringology/compression/LZ77Test.cpp b/alib2algo/test-src/stringology/compression/LZ77Test.cpp
new file mode 100644
index 0000000000..7d0d124a9e
--- /dev/null
+++ b/alib2algo/test-src/stringology/compression/LZ77Test.cpp
@@ -0,0 +1,111 @@
+#include "LZ77Test.h"
+
+#include <string/String.h>
+#include <stringology/compression/LZ77Compression.h>
+#include <stringology/compression/LZ77Decompression.h>
+
+#include <iostream>
+#include <tuple>
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION ( LZ77Test, "stringology" );
+CPPUNIT_TEST_SUITE_REGISTRATION ( LZ77Test );
+
+void LZ77Test::setUp ( ) {
+}
+
+void LZ77Test::tearDown ( ) {
+}
+
+void LZ77Test::testLZ77_1 ( ) {
+	std::string testStr = "aabaacaaaaaababab";
+
+	string::LinearString < char > string = string::stringFrom ( testStr );
+	std::vector < std::tuple < unsigned, unsigned, char > > res = stringology::compression::LZ77Compression::compress ( string, 6, 4 );
+
+	std::vector < std::tuple < unsigned, unsigned, char > > expectedOutput;
+
+	expectedOutput.push_back(std::make_tuple(0, 0, 'a' ) );
+	expectedOutput.push_back(std::make_tuple(1, 1, 'b' ) );
+	expectedOutput.push_back(std::make_tuple(3, 2, 'c' ) );
+	expectedOutput.push_back(std::make_tuple(3, 2, 'a' ) );
+	expectedOutput.push_back(std::make_tuple(1, 3, 'b' ) );
+	expectedOutput.push_back(std::make_tuple(2, 3, 'b' ) );
+
+	for ( const std::tuple < unsigned, unsigned, char > & resItem : res )
+		std::cout << std::get < 0 > ( resItem ) << " " << std::get < 1 > ( resItem ) << " " << std::get < 2 > ( resItem ) << std::endl;
+
+	CPPUNIT_ASSERT ( res == expectedOutput );
+
+}
+
+void LZ77Test::testLZ77_2 ( ) {
+
+	std::string testStr = "aacaacabcabaaac";
+
+	string::LinearString < char > string = string::stringFrom ( testStr );
+	std::vector < std::tuple < unsigned, unsigned, char > > res = stringology::compression::LZ77Compression::compress ( string, 6, 4 );
+
+	std::vector < std::tuple < unsigned, unsigned, char > > expectedOutput;
+
+	expectedOutput.push_back(std::make_tuple(0, 0, 'a' ) );
+	expectedOutput.push_back(std::make_tuple(1, 1, 'c' ) );
+	expectedOutput.push_back(std::make_tuple(3, 4, 'b' ) );
+	expectedOutput.push_back(std::make_tuple(3, 3, 'a' ) );
+	expectedOutput.push_back(std::make_tuple(1, 2, 'c' ) );
+
+	for ( const std::tuple < unsigned, unsigned, char > & resItem : res )
+		std::cout << std::get < 0 > ( resItem ) << " " << std::get < 1 > ( resItem ) << " " << std::get < 2 > ( resItem ) << std::endl;
+
+	CPPUNIT_ASSERT ( res == expectedOutput );
+}
+
+void LZ77Test::testLZ77Decompress1 ( ) {
+
+	std::vector < std::tuple < unsigned, unsigned, char > > input;
+
+	input.push_back(std::make_tuple(0, 0, 'a' ) );
+	input.push_back(std::make_tuple(1, 1, 'b' ) );
+	input.push_back(std::make_tuple(3, 2, 'c' ) );
+	input.push_back(std::make_tuple(3, 2, 'a' ) );
+	input.push_back(std::make_tuple(1, 3, 'b' ) );
+	input.push_back(std::make_tuple(2, 3, 'b' ) );
+
+	string::LinearString < char > res = stringology::compression::LZ77Decompression::decompress ( input );
+
+	std::string string = "aabaacaaaaaababab";
+	string::LinearString < char > expectedString = string::stringFrom ( string );
+
+	CPPUNIT_ASSERT ( res == expectedString );
+
+}
+
+void LZ77Test::testLZ77Decompress2 ( ) {
+
+	std::vector < std::tuple < unsigned, unsigned, char > > input;
+
+	input.push_back(std::make_tuple(0, 0, 'a' ) );
+	input.push_back(std::make_tuple(1, 1, 'c' ) );
+	input.push_back(std::make_tuple(3, 4, 'b' ) );
+	input.push_back(std::make_tuple(3, 3, 'a' ) );
+	input.push_back(std::make_tuple(1, 2, 'c' ) );
+
+	string::LinearString < char > res = stringology::compression::LZ77Decompression::decompress ( input );
+
+	std::string string = "aacaacabcabaaac";
+	string::LinearString < char > expectedString = string::stringFrom ( string );
+
+	CPPUNIT_ASSERT ( res == expectedString );
+
+}
+
+void LZ77Test::testLZ77Decompress3 ( ) {
+
+	std::string string = "";
+	string::LinearString < char > input = string::stringFrom ( string );
+
+	std::vector < std::tuple < unsigned, unsigned, char > > out = stringology::compression::LZ77Compression::compress ( input, 6, 4 );
+
+	string::LinearString < char > res = stringology::compression::LZ77Decompression::decompress ( out );
+
+	CPPUNIT_ASSERT ( input == res );
+}
diff --git a/alib2algo/test-src/string/compress/LZ77Test.h b/alib2algo/test-src/stringology/compression/LZ77Test.h
similarity index 60%
rename from alib2algo/test-src/string/compress/LZ77Test.h
rename to alib2algo/test-src/stringology/compression/LZ77Test.h
index 5e30daa043..823c3036b7 100644
--- a/alib2algo/test-src/string/compress/LZ77Test.h
+++ b/alib2algo/test-src/stringology/compression/LZ77Test.h
@@ -7,6 +7,9 @@ class LZ77Test : public CppUnit::TestFixture {
 	CPPUNIT_TEST_SUITE ( LZ77Test );
 	CPPUNIT_TEST ( testLZ77_1 );
 	CPPUNIT_TEST ( testLZ77_2 );
+	CPPUNIT_TEST ( testLZ77Decompress1 );
+	CPPUNIT_TEST ( testLZ77Decompress2 );
+	CPPUNIT_TEST ( testLZ77Decompress3 );
 	CPPUNIT_TEST_SUITE_END ( );
 
 public:
@@ -15,6 +18,10 @@ public:
 
 	void testLZ77_1 ( );
 	void testLZ77_2 ( );
+
+	void testLZ77Decompress1 ( );
+	void testLZ77Decompress2 ( );
+	void testLZ77Decompress3 ( );
 };
 
-#endif // LZ77_TEST
\ No newline at end of file
+#endif // LZ77_TEST
-- 
GitLab