Wordsearch Solver
trie.hpp
1 #ifndef TRIE_HPP
2 #define TRIE_HPP
3 
4 #include "wordsearch_solver/trie/node.hpp"
5 #include "wordsearch_solver/utility/flat_char_value_map.hpp"
6 
7 #include <fmt/core.h>
8 #include <fmt/format.h>
9 #include <fmt/ostream.h>
10 #include <fmt/ranges.h>
11 
12 #include <algorithm>
13 #include <cstdint>
14 #include <initializer_list>
15 #include <iterator>
16 #include <ostream>
17 #include <string>
18 #include <string_view>
19 #include <tuple>
20 #include <type_traits>
21 #include <utility>
22 #include <vector>
23 
24 // TODO: test this with const_iterator not a std::tuple, and try a simple user
25 // defined struct/pointer to make trivial type to help the optimiser? Not even
26 // sure if "trivial" means what I think it does anyway, remove this likely..
27 // TODO: maybe look into units library for the ascii/index conversion stuff, as
28 // that has already wasted a significant amount of time with offset stuff
29 // TODO: std::bitset size on this system is 8 bytes, even though it need only be
30 // 4 bytes (26 bits) for lowercase ascii. Could see if writing own node without
31 // std::bitset that is 4 bytes big changes performance due to whole thing being
32 // approx half size (better for cache).
33 
35 namespace trie {
36 
54 class Trie {
55 public:
56  Trie() = default;
57 
58  Trie(Trie&&) = default;
59  Trie& operator=(Trie&&) = default;
60 
65  Trie(const Trie&) = delete;
66  Trie& operator=(const Trie&) = delete;
67 
68  Trie(const std::initializer_list<std::string_view>& words);
69  Trie(const std::initializer_list<std::string>& words);
70  Trie(const std::initializer_list<const char*>& words);
71 
72  template <class Iterator1, class Iterator2>
73  Trie(Iterator1 first, const Iterator2 last);
74 
75  // TODO: constrain this (sfinae or concepts(>=c++20))
76  // Strings should be a range of strings
77  template <class Strings> explicit Trie(Strings&& strings_in);
78 
80  bool contains(std::string_view word) const;
81 
83  bool further(std::string_view word) const;
84 
86  template <class OutputIterator>
87  void contains_further(const std::string_view stem,
88  const std::string_view suffixes,
89  OutputIterator contains_further_it) const;
90 
91  std::size_t size() const;
92  bool empty() const;
93 
94  friend std::ostream& operator<<(std::ostream& os, const Trie& ct);
95 
96 private:
97  const Node* search(std::string_view word) const;
98  std::pair<Node*, bool> insert(std::string_view word);
99 
100  Node root_;
101  std::size_t size_;
103 };
104 
105 namespace detail {
106 
107 bool contains(const Node& node, std::string_view word);
108 bool further(const Node& node, std::string_view word);
109 
110 } // namespace detail
111 
112 } // namespace trie
113 
114 #include "wordsearch_solver/trie/trie.tpp"
115 
116 #endif // TRIE_HPP
A vector of edges to child nodes, sorted by edge child node character value, and a bool indicating wh...
Definition: node.hpp:23
Recursive immutable node based trie.
Definition: trie.hpp:54
bool further(std::string_view word) const
Check if this dictionary might contain words with word as a prefix.
Definition: trie.cpp:49
void contains_further(const std::string_view stem, const std::string_view suffixes, OutputIterator contains_further_it) const
For each char in suffix appended to stem, check whether this dictionary contains this word and if it ...
Definition: trie.tpp:39
Trie(const Trie &)=delete
std::pair< Node *, bool > insert(std::string_view word)
Definition: trie.cpp:113
const Node * search(std::string_view word) const
Definition: trie.cpp:80
bool contains(std::string_view word) const
Check if this dictionary contains word.
Definition: trie.cpp:45
A small cache for each character of a word and an associated value, such as iterator into a trie for ...
Definition: flat_char_value_map.hpp:30
namespace trie
Definition: node.hpp:18