refactor: add WordList type

This commit is contained in:
Michael Mandl 2024-03-21 08:55:44 +01:00
parent dae5445efc
commit 48f05ddb4f
Signed by: mandlm
GPG key ID: 4AA25D647AA54CC7
18 changed files with 111 additions and 92 deletions

View file

@ -8,9 +8,7 @@
#include "sorted_linear_finder.h" #include "sorted_linear_finder.h"
#include "timer.h" #include "timer.h"
#include "tree_finder.h" #include "tree_finder.h"
#include "word_list_generator.h"
#include <fstream>
#include <sstream> #include <sstream>
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
@ -55,7 +53,9 @@ void MainWindow::setupWordList() {
void MainWindow::generateWordList() { void MainWindow::generateWordList() {
Timer timer; Timer timer;
word_list_ = WordListGenerator::generate(ui->wordListSizeSelector->value()); word_list_ = WordList::fourCaps()
.multiply(ui->wordListSizeSelector->value())
.shuffle();
timer.stop(); timer.stop();
std::stringstream status_message; std::stringstream status_message;
@ -64,17 +64,10 @@ void MainWindow::generateWordList() {
} }
void MainWindow::loadWordList(std::filesystem::path path) { void MainWindow::loadWordList(std::filesystem::path path) {
word_list_.clear();
Timer timer; Timer timer;
std::ifstream ifs(path); word_list_ = WordList::fromFile("words.txt")
.multiply(ui->wordListSizeSelector->value())
std::string line; .shuffle();
while (std::getline(ifs, line)) {
for (auto i = 0; i < ui->wordListSizeSelector->value(); ++i) {
word_list_.emplace_back(line);
}
}
timer.stop(); timer.stop();
std::stringstream status_message; std::stringstream status_message;

View file

@ -2,6 +2,7 @@
#define MAINWINDOW_H #define MAINWINDOW_H
#include "finder.h" #include "finder.h"
#include "word_list.h"
#include <QMainWindow> #include <QMainWindow>
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QStringListModel> #include <QStringListModel>
@ -17,7 +18,7 @@ class MainWindow : public QMainWindow {
Q_OBJECT Q_OBJECT
private: private:
std::vector<std::string> word_list_; WordList word_list_;
QStringListModel result_model_; QStringListModel result_model_;
QStandardItemModel search_algorithms_; QStandardItemModel search_algorithms_;
QStandardItemModel word_list_sources_; QStandardItemModel word_list_sources_;

View file

@ -7,8 +7,8 @@ project(
add_library( add_library(
vector_search STATIC vector_search STATIC
src/word_list_generator.cpp src/word_list.cpp
include/word_list_generator.h include/word_list.h
src/linear_finder.cpp src/linear_finder.cpp
include/linear_finder.h include/linear_finder.h
src/sorted_linear_finder.cpp src/sorted_linear_finder.cpp

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "finder.h" #include "finder.h"
#include "word_list.h"
#include <map> #include <map>
#include <vector> #include <vector>
@ -10,7 +11,7 @@ private:
std::map<char, std::vector<const std::string *>> groups_; std::map<char, std::vector<const std::string *>> groups_;
public: public:
GroupedFinder(const std::vector<std::string> &word_list); GroupedFinder(const WordList &word_list);
virtual std::forward_list<const std::string *> virtual std::forward_list<const std::string *>
find_prefix(std::string_view search_term) const override; find_prefix(std::string_view search_term) const override;

View file

@ -1,17 +1,15 @@
#pragma once #pragma once
#include "finder.h" #include "finder.h"
#include "word_list.h"
#include <vector>
using std::vector;
class LinearFinder : public Finder { class LinearFinder : public Finder {
private: private:
const vector<std::string> &word_list_; const WordList &word_list_;
public: public:
LinearFinder(const vector<std::string> &word_list); LinearFinder(const WordList &word_list);
std::forward_list<const std::string *> std::forward_list<const std::string *>
find_prefix(std::string_view search_term) const override; find_prefix(std::string_view search_term) const override;
}; };

View file

@ -1,15 +1,14 @@
#pragma once #pragma once
#include "finder.h" #include "finder.h"
#include "word_list.h"
#include <vector>
class ParallelFinder : public Finder { class ParallelFinder : public Finder {
private: private:
const std::vector<std::string> &word_list_; const WordList &word_list_;
public: public:
ParallelFinder(const std::vector<std::string> &word_list); ParallelFinder(const WordList &word_list);
std::forward_list<const std::string *> std::forward_list<const std::string *>
find_prefix(std::string_view search_term) const override; find_prefix(std::string_view search_term) const override;

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "finder.h" #include "finder.h"
#include "word_list.h"
#include <vector> #include <vector>
@ -9,7 +10,7 @@ private:
std::vector<const std::string *> word_list_; std::vector<const std::string *> word_list_;
public: public:
SortedLinearFinder(const std::vector<std::string> &word_list); SortedLinearFinder(const WordList &word_list);
std::forward_list<const std::string *> std::forward_list<const std::string *>
find_prefix(std::string_view search_term) const override; find_prefix(std::string_view search_term) const override;

View file

@ -1,9 +1,9 @@
#pragma once #pragma once
#include "finder.h" #include "finder.h"
#include "word_list.h"
#include <map> #include <map>
#include <vector>
class SearchTreeNode { class SearchTreeNode {
private: private:
@ -19,7 +19,7 @@ public:
class SearchTree : public SearchTreeNode { class SearchTree : public SearchTreeNode {
public: public:
SearchTree(const std::vector<std::string> &word_list); SearchTree(const WordList &word_list);
}; };
class TreeFinder : public Finder { class TreeFinder : public Finder {
@ -27,7 +27,7 @@ private:
SearchTree search_tree_; SearchTree search_tree_;
public: public:
TreeFinder(const std::vector<std::string> &word_list); TreeFinder(const WordList &word_list);
virtual std::forward_list<const std::string *> virtual std::forward_list<const std::string *>
find_prefix(std::string_view search_term) const override; find_prefix(std::string_view search_term) const override;

View file

@ -0,0 +1,14 @@
#pragma once
#include <filesystem>
#include <string>
#include <vector>
class WordList : public std::vector<std::string> {
public:
WordList &multiply(size_t factor);
WordList &shuffle();
static WordList fourCaps();
static WordList fromFile(const std::filesystem::path &path);
};

View file

@ -1,13 +0,0 @@
#pragma once
#include <string>
#include <vector>
class WordListGenerator {
private:
static const std::string charset_;
public:
WordListGenerator() = delete;
static std::vector<std::string> generate(const size_t multiplier = 1);
};

View file

@ -8,7 +8,7 @@
using std::mutex, std::vector, std::thread, std::lock_guard, std::string, using std::mutex, std::vector, std::thread, std::lock_guard, std::string,
std::forward_list, std::string_view; std::forward_list, std::string_view;
GroupedFinder::GroupedFinder(const std::vector<string> &word_list) { GroupedFinder::GroupedFinder(const WordList &word_list) {
for (const auto &word : word_list) { for (const auto &word : word_list) {
groups_[word.front()].push_back(&word); groups_[word.front()].push_back(&word);
} }

View file

@ -4,8 +4,7 @@
using std::string, std::forward_list, std::string_view; using std::string, std::forward_list, std::string_view;
LinearFinder::LinearFinder(const vector<string> &word_list) LinearFinder::LinearFinder(const WordList &word_list) : word_list_(word_list) {}
: word_list_(word_list) {}
forward_list<const string *> forward_list<const string *>
LinearFinder::find_prefix(string_view search_term) const { LinearFinder::find_prefix(string_view search_term) const {

View file

@ -6,7 +6,7 @@
using std::mutex, std::thread, std::lock_guard, std::vector, std::forward_list, using std::mutex, std::thread, std::lock_guard, std::vector, std::forward_list,
std::string, std::string_view; std::string, std::string_view;
ParallelFinder::ParallelFinder(const vector<string> &word_list) ParallelFinder::ParallelFinder(const WordList &word_list)
: word_list_(word_list) {} : word_list_(word_list) {}
forward_list<const string *> forward_list<const string *>
@ -28,7 +28,7 @@ ParallelFinder::find_prefix(string_view search_term) const {
: (thread_index + 1) * (word_list_size / thread_count); : (thread_index + 1) * (word_list_size / thread_count);
threads.emplace_back( threads.emplace_back(
[](const vector<string> &word_list, const string_view &search_term, [](const WordList &word_list, const string_view &search_term,
forward_list<const string *> &result, size_t start_index, forward_list<const string *> &result, size_t start_index,
size_t end_index, mutex &result_mutex) { size_t end_index, mutex &result_mutex) {
forward_list<const string *> thread_results; forward_list<const string *> thread_results;

View file

@ -3,9 +3,9 @@
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
using std::vector, std::forward_list, std::string, std::string_view; using std::forward_list, std::string, std::string_view;
SortedLinearFinder::SortedLinearFinder(const vector<string> &word_list) { SortedLinearFinder::SortedLinearFinder(const WordList &word_list) {
std::transform(word_list.cbegin(), word_list.cend(), std::transform(word_list.cbegin(), word_list.cend(),
std::back_inserter(word_list_), std::back_inserter(word_list_),
[](const string &word) { return &word; }); [](const string &word) { return &word; });

View file

@ -1,6 +1,6 @@
#include "tree_finder.h" #include "tree_finder.h"
using std::string, std::string_view, std::forward_list, std::vector; using std::string, std::string_view, std::forward_list;
void SearchTreeNode::insert(string_view partial_word, void SearchTreeNode::insert(string_view partial_word,
const string *original_word) { const string *original_word) {
@ -35,14 +35,13 @@ forward_list<const string *> SearchTreeNode::words() const {
return results; return results;
}; };
SearchTree::SearchTree(const vector<string> &word_list) { SearchTree::SearchTree(const WordList &word_list) {
for (const auto &word : word_list) { for (const auto &word : word_list) {
insert(string_view(word), &word); insert(string_view(word), &word);
} }
} }
TreeFinder::TreeFinder(const vector<string> &word_list) TreeFinder::TreeFinder(const WordList &word_list) : search_tree_(word_list) {}
: search_tree_(word_list) {}
forward_list<const string *> forward_list<const string *>
TreeFinder::find_prefix(string_view search_term) const { TreeFinder::find_prefix(string_view search_term) const {

View file

@ -0,0 +1,59 @@
#include "word_list.h"
#include <algorithm>
#include <fstream>
#include <random>
WordList &WordList::multiply(size_t factor) {
WordList result;
result.reserve(size() * factor);
for (auto time = 0; time < factor; ++time) {
std::copy(cbegin(), cend(), std::back_inserter(result));
}
std::swap(*this, result);
return *this;
};
WordList &WordList::shuffle() {
std::random_device random_device;
std::mt19937 random_number_generator(random_device());
std::shuffle(begin(), end(), random_number_generator);
return *this;
}
WordList WordList::fourCaps() {
const static std::string charset_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
WordList word_list;
word_list.reserve(std::pow(charset_.length(), 4));
for (auto char_1 : charset_) {
for (auto char_2 : charset_) {
for (auto char_3 : charset_) {
for (auto char_4 : charset_) {
word_list.emplace_back(
std::initializer_list<char>({char_1, char_2, char_3, char_4}));
}
}
}
}
return word_list;
};
WordList WordList::fromFile(const std::filesystem::path &path) {
WordList word_list;
std::ifstream ifs(path);
std::string line;
while (std::getline(ifs, line)) {
word_list.emplace_back(line);
}
return word_list;
}

View file

@ -1,32 +0,0 @@
#include "word_list_generator.h"
#include <algorithm>
#include <cmath>
#include <random>
const std::string WordListGenerator::charset_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::vector<std::string> WordListGenerator::generate(const size_t multiplier) {
std::vector<std::string> word_list;
word_list.reserve(multiplier * std::pow(charset_.length(), 4));
for (auto char_1 : charset_) {
for (auto char_2 : charset_) {
for (auto char_3 : charset_) {
for (auto char_4 : charset_) {
for (auto i = 0; i < multiplier; ++i) {
word_list.emplace_back(
std::initializer_list<char>({char_1, char_2, char_3, char_4}));
}
}
}
}
}
std::random_device random_device;
std::mt19937 random_number_generator(random_device());
std::shuffle(word_list.begin(), word_list.end(), random_number_generator);
return word_list;
}

View file

@ -4,18 +4,18 @@
#include "sorted_linear_finder.h" #include "sorted_linear_finder.h"
#include "timer.h" #include "timer.h"
#include "tree_finder.h" #include "tree_finder.h"
#include "word_list_generator.h" #include "word_list.h"
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
using std::string, std::string_view, std::vector, std::cout, std::endl; using std::string, std::string_view, std::cout, std::endl;
vector<string> generate_word_list(size_t size_factor = 1) { WordList generate_word_list(size_t size_factor = 1) {
cout << endl << "generating word list (" << size_factor << "x)" << endl; cout << endl << "generating word list (" << size_factor << "x)" << endl;
Timer generator_timer; Timer generator_timer;
auto word_list = WordListGenerator::generate(size_factor); auto word_list = WordList::fourCaps().multiply(size_factor).shuffle();
generator_timer.stop(); generator_timer.stop();
cout << "word list generator took " << generator_timer << endl; cout << "word list generator took " << generator_timer << endl;
@ -36,7 +36,7 @@ void test_finder_search(Finder &finder, string_view name,
} }
template <typename FINDER> template <typename FINDER>
void test_finder(const vector<string> &word_list, string_view finder_name) { void test_finder(const WordList &word_list, string_view finder_name) {
cout << endl << "running " << finder_name << endl; cout << endl << "running " << finder_name << endl;
Timer constructor_timer; Timer constructor_timer;