From 26d3839832f31ce7b64303838bea8b2448c7ea5a Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Wed, 20 Mar 2024 20:50:43 +0100 Subject: [PATCH] feat: add sorted linear finder --- QVectorSearch/mainwindow.cpp | 9 ++++-- lib_vector_search/CMakeLists.txt | 2 ++ .../include/sorted_linear_finder.h | 16 ++++++++++ .../src/sorted_linear_finder.cpp | 32 +++++++++++++++++++ vector_search_cli/main.cpp | 27 +++++++++++++--- 5 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 lib_vector_search/include/sorted_linear_finder.h create mode 100644 lib_vector_search/src/sorted_linear_finder.cpp diff --git a/QVectorSearch/mainwindow.cpp b/QVectorSearch/mainwindow.cpp index cb0cad2..5854f7e 100644 --- a/QVectorSearch/mainwindow.cpp +++ b/QVectorSearch/mainwindow.cpp @@ -5,6 +5,7 @@ #include "grouped_finder.h" #include "linear_finder.h" #include "parallel_finder.h" +#include "sorted_linear_finder.h" #include "timer.h" #include "tree_finder.h" #include "word_list_generator.h" @@ -26,6 +27,7 @@ MainWindow::~MainWindow() { delete ui; } void MainWindow::setupAlgorithmSelector() { search_algorithms_.appendRow(new QStandardItem("Linear search")); + search_algorithms_.appendRow(new QStandardItem("Sorted linear search")); search_algorithms_.appendRow(new QStandardItem("Parallel search")); search_algorithms_.appendRow(new QStandardItem("Tree search")); search_algorithms_.appendRow(new QStandardItem("Grouped search")); @@ -69,12 +71,15 @@ void MainWindow::createSelectedFinder() { finder_ = std::make_unique(word_list_); break; case 1: - finder_ = std::make_unique(word_list_); + finder_ = std::make_unique(word_list_); break; case 2: - finder_ = std::make_unique(word_list_); + finder_ = std::make_unique(word_list_); break; case 3: + finder_ = std::make_unique(word_list_); + break; + case 4: finder_ = std::make_unique(word_list_); break; } diff --git a/lib_vector_search/CMakeLists.txt b/lib_vector_search/CMakeLists.txt index be48138..504ab60 100644 --- a/lib_vector_search/CMakeLists.txt +++ b/lib_vector_search/CMakeLists.txt @@ -13,6 +13,8 @@ add_library( include/timer.h src/linear_finder.cpp include/linear_finder.h + src/sorted_linear_finder.cpp + include/sorted_linear_finder.h src/parallel_finder.cpp include/parallel_finder.h src/tree_finder.cpp diff --git a/lib_vector_search/include/sorted_linear_finder.h b/lib_vector_search/include/sorted_linear_finder.h new file mode 100644 index 0000000..f49c27e --- /dev/null +++ b/lib_vector_search/include/sorted_linear_finder.h @@ -0,0 +1,16 @@ +#pragma once + +#include "finder.h" + +#include + +class SortedLinearFinder : public Finder { +private: + std::vector word_list_; + +public: + SortedLinearFinder(const std::vector &word_list); + + std::forward_list + find_prefix(std::string_view search_term) const override; +}; diff --git a/lib_vector_search/src/sorted_linear_finder.cpp b/lib_vector_search/src/sorted_linear_finder.cpp new file mode 100644 index 0000000..e904d6f --- /dev/null +++ b/lib_vector_search/src/sorted_linear_finder.cpp @@ -0,0 +1,32 @@ +#include "sorted_linear_finder.h" + +#include +#include + +using std::vector, std::forward_list, std::string, std::string_view; + +SortedLinearFinder::SortedLinearFinder(const vector &word_list) { + std::transform(word_list.cbegin(), word_list.cend(), + std::back_inserter(word_list_), + [](const string &word) { return &word; }); + + std::sort( + word_list_.begin(), word_list_.end(), + [](const string *left, const string *right) { return *left < *right; }); +} +forward_list +SortedLinearFinder::find_prefix(string_view search_term) const { + forward_list matching_words; + + bool in_range = false; + for (const auto *word : word_list_) { + if (word->starts_with(search_term)) { + matching_words.push_front(word); + in_range = true; + } else if (in_range) { + break; + } + } + + return matching_words; +} diff --git a/vector_search_cli/main.cpp b/vector_search_cli/main.cpp index 7417e9b..f2ad6cf 100644 --- a/vector_search_cli/main.cpp +++ b/vector_search_cli/main.cpp @@ -1,6 +1,7 @@ #include "grouped_finder.h" #include "linear_finder.h" #include "parallel_finder.h" +#include "sorted_linear_finder.h" #include "timer.h" #include "tree_finder.h" #include "word_list_generator.h" @@ -10,11 +11,11 @@ using std::string, std::string_view, std::vector, std::cout, std::endl; -vector generate_word_list() { - cout << "\ngenerating word list" << endl; +vector generate_word_list(size_t size_factor = 1) { + cout << "\ngenerating word list (" << size_factor << "x)" << endl; Timer generator_timer; - auto word_list = WordListGenerator::generate(5); + auto word_list = WordListGenerator::generate(size_factor); generator_timer.stop(); cout << "word list generator took " << generator_timer << endl; @@ -43,15 +44,32 @@ void test_finder(Finder &finder, std::string_view name) { void test_linear_finder(const vector &word_list) { cout << "\nrunning linear finder" << endl; + Timer constructor_timer; LinearFinder linear_finder(word_list); + constructor_timer.stop(); + cout << "linear finder constructor took " << constructor_timer << endl; test_finder(linear_finder, "linear finder"); } +void test_sorted_linear_finder(const vector &word_list) { + cout << "\nrunning sorted linear finder" << endl; + + Timer constructor_timer; + SortedLinearFinder sorted_linear_finder(word_list); + constructor_timer.stop(); + cout << "sorted linear finder constructor took " << constructor_timer << endl; + + test_finder(sorted_linear_finder, "sorted linear finder"); +} + void test_parallel_finder(const vector &word_list) { cout << "\nrunning parallel finder" << endl; + Timer constructor_timer; ParallelFinder parallel_finder(word_list); + constructor_timer.stop(); + cout << "linear finder constructor took " << constructor_timer << endl; test_finder(parallel_finder, "parallel finder"); } @@ -81,9 +99,10 @@ void test_grouped_finder(const vector &word_list) { int main(int argc, char *argv[]) { cout << "\n== VectorSearch ==" << endl; - auto word_list = generate_word_list(); + auto word_list = generate_word_list(5); test_linear_finder(word_list); + test_sorted_linear_finder(word_list); test_parallel_finder(word_list); test_tree_finder(word_list); test_grouped_finder(word_list);