better partitions system in global_info, trie in utils

This commit is contained in:
ProgramSnail 2023-05-11 14:56:27 +03:00
parent 6e487c8fd9
commit a97a6125de
3 changed files with 130 additions and 8 deletions

View file

@ -3,6 +3,8 @@
#include <cstdlib>
#include <vector>
#include <string>
#include <memory>
#include <optional>
#include <unordered_map>
namespace utils {
@ -64,6 +66,106 @@ private:
std::unordered_map<T, IdType> value_to_id_;
};
template<typename Key, typename Value>
class Trie { // optimize ??
public:
Trie() {
verticles_.emplace_back();
}
bool Insert(const std::vector<Key>& path, const Value& value) {
return RecursiveInsert(verticles_[0], path, 0, value);
}
std::optional<Value*> Find(const std::vector<Key>& path) {
return RecursiveFind(verticles_[0], path, 0);
}
std::vector<Value*> FindByPrefix(const std::vector<Key>& path) {
return RecursiveFindByPrefix(verticles_[0], path, 0);
}
private:
struct Vertex {
std::unordered_map<Key, size_t> children_;
std::optional<Value> value;
};
bool RecursiveInsert(Vertex& vertex,
const std::vector<Key>& path,
size_t path_position,
const Value& value) {
if (path_position == path.size()) {
if (vertex.value.has_value()) {
return false;
}
vertex.value = value;
return true;
}
auto child_iter = vertex.children_.find(path[path_position]);
if (child_iter != vertex.children_.end()) {
return RecursiveInsert(verticles_[child_iter->second], path, path_position + 1, value);
}
vertex.children_[path[path_position]] = verticles_.size();
verticles_.emplace_back();
return RecursiveInsert(verticles_.back(), path, path_position + 1, value);
}
std::optional<Value*> RecursiveFind(Vertex& vertex,
const std::vector<Key>& path,
size_t path_position) {
if (path_position == path.size()) {
if (vertex.value.has_value()) {
return std::nullopt;
}
return &vertex.value.value();
}
auto child_iter = vertex.children_.find(path[path_position]);
if (child_iter != vertex.children_.end()) {
return RecursiveFind(verticles_[child_iter->second], path, path_position + 1);
}
return std::nullopt;
}
std::vector<Value*> RecursiveFindByPrefix(Vertex& vertex,
const std::vector<Key>& path,
size_t path_position) {
if (path_position == path.size()) {
std::vector<Value*> ans;
RecursiveGetAll(vertex, ans);
return ans;
}
auto child_iter = vertex.children_.find(path[path_position]);
if (child_iter != vertex.children_.end()) {
return RecursiveFindByPrefix(verticles_[child_iter->second], path, path_position + 1);
}
return {};
}
void RecursiveGetAll(Vertex& vertex, std::vector<Value*>& accumulator) {
std::vector<Value*> ans;
if (vertex.value.has_value()) {
accumulator.push_back(&vertex.value.value());
}
for (auto& child : vertex.children_) {
RecursiveGetAll(verticles_[child.second], accumulator);
}
}
private:
std::vector<Vertex> verticles_;
};
class GroupsManager { // TODO: recall right algorithm name
public:
GroupsManager() = default;