From c6b63291347c8cddbd86d014279fb4302eca0f99 Mon Sep 17 00:00:00 2001 From: Knyffen Date: Sun, 14 Nov 2021 16:19:11 +0100 Subject: [PATCH] Abstrack simple string matching to a process The process contains the fingerprinting function along with a queue representing the sliding window. This means that the user no longer needs to remember the outgoing character when streaming the text. --- Makefile | 7 +++++-- Rabin_fingerprint.hpp | 2 +- V1/simple_string_matching | Bin 58864 -> 58864 bytes processes.cpp | 29 +++++++++++++++++++++++++++++ processes.hpp | 23 +++++++++++++++++++++++ simple_string_matching | Bin 0 -> 92408 bytes simple_string_matching.cpp | 28 +++++++++++----------------- 7 files changed, 69 insertions(+), 20 deletions(-) create mode 100644 processes.cpp create mode 100644 processes.hpp create mode 100755 simple_string_matching diff --git a/Makefile b/Makefile index cc3cf4b..1ca0280 100644 --- a/Makefile +++ b/Makefile @@ -24,8 +24,8 @@ LDLIBS = # library flags # -llapacke (LAPACK) NOTE: The order of "-llapacke -llapack -lblas" is very important #LINK.o = $(CXX) $(LDFLAGS) # use CXX for linking -simple_string_matching: simple_string_matching.o Rabin_fingerprint.o general_library.o - $(CXX) $(CXXFLAGS) simple_string_matching.o Rabin_fingerprint.o general_library.o -o simple_string_matching +simple_string_matching: simple_string_matching.o Rabin_fingerprint.o general_library.o processes.o + $(CXX) $(CXXFLAGS) simple_string_matching.o Rabin_fingerprint.o general_library.o processes.o -o simple_string_matching simple_string_matching.o: simple_string_matching.cpp $(CXX) $(CXXFLAGS) -c simple_string_matching.cpp @@ -36,6 +36,9 @@ Rabin_fingerprint.o: Rabin_fingerprint.cpp Rabin_fingerprint.hpp general_library.o: general_library.cpp general_library.hpp $(CXX) $(CXXFLAGS) -c general_library.cpp +processes.o: processes.cpp processes.hpp + $(CXX) $(CXXFLAGS) -c processes.cpp + porat-porat: porat-porat.cpp # Tell the compiler that 'clean' isn't referring to a file diff --git a/Rabin_fingerprint.hpp b/Rabin_fingerprint.hpp index 01ff03c..f9b74dd 100644 --- a/Rabin_fingerprint.hpp +++ b/Rabin_fingerprint.hpp @@ -14,7 +14,7 @@ class Rabin_fingerprint { void push_bit (bool b); void shift_bit (bool b); void slide_char (char c_in, char c_out); - void slide_bit (bool b1, bool b2); + void slide_bit (bool b_in, bool b_out); uint32_t get_fingerprint(); diff --git a/V1/simple_string_matching b/V1/simple_string_matching index 36894f0f8479a9aa5ee349f89eabeeae2b455094..54fb4194b3c44f878e895505cd0c1124ad79bf90 100755 GIT binary patch delta 2922 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 diff --git a/processes.cpp b/processes.cpp new file mode 100644 index 0000000..3f53510 --- /dev/null +++ b/processes.cpp @@ -0,0 +1,29 @@ +#include "processes.hpp" + +Rabin_fingerprint_process::Rabin_fingerprint_process(uint32_t irr_poly, size_t window_size_in_bits) + : window_size_in_bits(window_size_in_bits), + phi(irr_poly, window_size_in_bits) +{} + +void Rabin_fingerprint_process::stream_char (char c) { + std::bitset<8> b(c); + for (char i = 7; i >= 0; i--) { + stream_bit((bool)b[i]); + } +} + +void Rabin_fingerprint_process::stream_bit (bool b) { + if (window.size() == window_size_in_bits) { + window.push(b); + bool b_out = window.front(); + window.pop(); + phi.slide_bit(b, b_out); + } else { + window.push(b); + phi.push_bit(b); + } +} + +uint32_t Rabin_fingerprint_process::get_fingerprint () { + return phi.get_fingerprint(); +} diff --git a/processes.hpp b/processes.hpp new file mode 100644 index 0000000..05561b1 --- /dev/null +++ b/processes.hpp @@ -0,0 +1,23 @@ +#ifndef PROCESSES_H +#define PROCESSES_H + +#include "Rabin_fingerprint.hpp" +#include "general_library.hpp" + +#include +#include + +class Rabin_fingerprint_process { + public: + Rabin_fingerprint_process(uint32_t irr_poly, size_t window_size_in_bits); + void stream_char(char c); + void stream_bit(bool b); + uint32_t get_fingerprint(); + + private: + std::queue window; + size_t window_size_in_bits; + Rabin_fingerprint phi; +}; + +#endif diff --git a/simple_string_matching b/simple_string_matching new file mode 100755 index 0000000000000000000000000000000000000000..4dd651934aaa81dbd90e6ec3c046fabc43570e38 GIT binary patch literal 92408 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 b3k?g1uX0_1z6D=={r^Ilmdj2D=d|+wkB@)Q literal 0 HcmV?d00001 diff --git a/simple_string_matching.cpp b/simple_string_matching.cpp index 84520a0..735ceac 100644 --- a/simple_string_matching.cpp +++ b/simple_string_matching.cpp @@ -1,6 +1,7 @@ /* #define NDEBUG */ -#include "Rabin_fingerprint.hpp" -#include "general_library.hpp" +/* #include "Rabin_fingerprint.hpp" */ +/* #include "general_library.hpp" */ +#include "processes.hpp" #include #include @@ -21,11 +22,7 @@ int main() { std::string T( (std::istreambuf_iterator(ifs) ), (std::istreambuf_iterator() ) ); - /* std::string T = "Hello, this is my test string averylongword is a necessary word to exceed the 32 bit window."; */ - // Test without the modulo polynomial - and two matches std::string P = "word"; - // Test with the modulo polynomial - /* std::string P = "averylongword"; */ std::cout << "Searching for pattern:" << std::endl; std::cout << " " << P << std::endl; @@ -33,27 +30,24 @@ int main() { /* std::cout << " " << T << std::endl; */ std::cout << std::endl; - /* uint32_t polynomial = pow(2, 30) + pow(2, 2) + 1; // x^31 + x^3 + 1 */ - uint32_t polynomial = get_random_irreducible_polynomial_in_Z2(31); - /* uint32_t polynomial = 0b11010011100100000111101011110111; */ - // Test without the modulo polynomial + uint32_t irreducible_polynomial = get_random_irreducible_polynomial_in_Z2(31); size_t window_size_in_bits = P.length()*8; // Hash the pattern - Rabin_fingerprint fP(polynomial, window_size_in_bits); + Rabin_fingerprint_process phiP(irreducible_polynomial, (size_t)window_size_in_bits); for (char c : P) - fP.push_char(c); + phiP.stream_char(c); // Hash the text - Rabin_fingerprint fT(polynomial, window_size_in_bits); + Rabin_fingerprint_process phiT(irreducible_polynomial, window_size_in_bits); for (size_t i = 0; i < P.length(); i++) - fT.push_char(T[i]); - if (fT.get_fingerprint() == fP.get_fingerprint()) + phiT.stream_char(T[i]); + if (phiT.get_fingerprint() == phiP.get_fingerprint()) print_match(0, P.length(), T); for (size_t i = P.length(); i < T.length(); i++) { - fT.slide_char(T[i], T[i-P.length()]); - if (fT.get_fingerprint() == fP.get_fingerprint()) + phiT.stream_char(T[i]); + if (phiT.get_fingerprint() == phiP.get_fingerprint()) print_match(i-P.length()+1, P.length(), T); }