diff options
Diffstat (limited to 'prefix_search.h')
| -rw-r--r-- | prefix_search.h | 85 |
1 files changed, 85 insertions, 0 deletions
| diff --git a/prefix_search.h b/prefix_search.h new file mode 100644 index 0000000..fe69ef7 --- /dev/null +++ b/prefix_search.h | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | #ifndef PREFIX_SEARCH_H_A6672A1D | ||
| 2 | #define PREFIX_SEARCH_H_A6672A1D | ||
| 3 | |||
| 4 | #include <unordered_map> | ||
| 5 | #include <vector> | ||
| 6 | #include <stdexcept> | ||
| 7 | |||
| 8 | template <typename T> | ||
| 9 | class prefix_search { | ||
| 10 | public: | ||
| 11 | |||
| 12 | prefix_search(size_t depth = 0) : depth_(depth), count_(0) | ||
| 13 | { | ||
| 14 | } | ||
| 15 | |||
| 16 | size_t getDepth() const | ||
| 17 | { | ||
| 18 | return depth_; | ||
| 19 | } | ||
| 20 | |||
| 21 | size_t getCount() const | ||
| 22 | { | ||
| 23 | return count_; | ||
| 24 | } | ||
| 25 | |||
| 26 | void add(std::string& key, T val, size_t i = 0) | ||
| 27 | { | ||
| 28 | count_++; | ||
| 29 | |||
| 30 | if (i == key.length()) | ||
| 31 | { | ||
| 32 | elements_.push_back(val); | ||
| 33 | } else { | ||
| 34 | char next = key.at(i); | ||
| 35 | |||
| 36 | if (!children_.count(next)) | ||
| 37 | { | ||
| 38 | children_.emplace(next, prefix_search<T> { depth_ + 1 } ); | ||
| 39 | } | ||
| 40 | |||
| 41 | children_.at(next).add(key, val, i + 1); | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | T at(size_t i) const | ||
| 46 | { | ||
| 47 | if (i < elements_.size()) | ||
| 48 | { | ||
| 49 | return elements_.at(i); | ||
| 50 | } else { | ||
| 51 | i -= elements_.size(); | ||
| 52 | |||
| 53 | for (const auto& mapping : children_) | ||
| 54 | { | ||
| 55 | if (mapping.second.count_ > i) | ||
| 56 | { | ||
| 57 | return mapping.second.at(i); | ||
| 58 | } else { | ||
| 59 | i -= mapping.second.count_; | ||
| 60 | } | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | throw std::out_of_range("Index out of range"); | ||
| 65 | } | ||
| 66 | |||
| 67 | const prefix_search<T>& find(const std::string& val, size_t i) const | ||
| 68 | { | ||
| 69 | if (i == val.length() || !children_.count(val.at(i))) | ||
| 70 | { | ||
| 71 | return *this; | ||
| 72 | } | ||
| 73 | |||
| 74 | return children_.at(val.at(i)).find(val, i+1); | ||
| 75 | } | ||
| 76 | |||
| 77 | private: | ||
| 78 | |||
| 79 | size_t depth_; | ||
| 80 | size_t count_; | ||
| 81 | std::unordered_map<char, prefix_search<T>> children_; | ||
| 82 | std::vector<T> elements_; | ||
| 83 | }; | ||
| 84 | |||
| 85 | #endif /* end of include guard: PREFIX_SEARCH_H_A6672A1D */ | ||
