trie.tpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. //
  2. // trie_impl.hpp
  3. // trie
  4. //
  5. // Created by Sam Jaffe on 6/16/17.
  6. //
  7. #pragma once
  8. #include "trie.hpp"
  9. #include "trie_iterator.hpp"
  10. // n := total elements
  11. // d := average depth
  12. // Stack: O(1)
  13. // Operations: O(n)
  14. template <typename K, typename V, typename C>
  15. trie<K, V, C>::trie(trie const & other) : value_(other.value_) {
  16. impl_iterator current{this};
  17. for (const_iterator it = ++other.begin(), end = {}; it != end; ++it) {
  18. while (current.keys_.size() >= it.keys_.size()) {
  19. current.pop();
  20. }
  21. auto tmp = current.root().insert(it.keys_.back(), *it).first;
  22. current.push(tmp.current());
  23. }
  24. }
  25. template <typename K, typename V, typename C>
  26. trie<K, V, C>::trie(mapped_type const & root, std::map<K, trie, C> && children)
  27. : value_(root) {
  28. for (auto & pair : children) {
  29. operator[](pair.first) = std::move(pair.second);
  30. }
  31. }
  32. template <typename K, typename V, typename C>
  33. auto trie<K, V, C>::operator=(mapped_type const & value) -> trie & {
  34. value_ = value;
  35. return *this;
  36. }
  37. template <typename K, typename V, typename C>
  38. auto trie<K, V, C>::operator=(trie const & other) -> trie & {
  39. trie tmp{other};
  40. swap(*this, tmp);
  41. return *this;
  42. }
  43. template <typename K, typename V, typename C>
  44. auto trie<K, V, C>::operator=(trie && other) -> trie & {
  45. swap(*this, other);
  46. return *this;
  47. }
  48. // n := total elements
  49. // d := average depth
  50. // Operations: O(log(n)/d)
  51. template <typename K, typename V, typename C>
  52. template <typename Key>
  53. void trie<K, V, C>::insert_impl(impl_iterator & out, bool & create,
  54. Key && key) {
  55. auto it = impl_.lower_bound(key);
  56. if (it == impl_.end() || key_compare()(key, it->first)) {
  57. create = true;
  58. it = impl_.emplace_hint(it, key, pointers::make_value<trie>());
  59. }
  60. out.push({it, impl_.end()});
  61. }
  62. // n := total elements
  63. // d := average depth
  64. // Operations: O(log(n))
  65. template <typename K, typename V, typename C>
  66. template <typename KS, typename... Args>
  67. auto trie<K, V, C>::emplace_impl(KS && keys, Args &&... args)
  68. -> std::pair<impl_iterator, bool> {
  69. impl_iterator it{this};
  70. bool create{false};
  71. for (auto && key : keys) {
  72. it.root().insert_impl(it, create, std::forward<decltype(key)>(key));
  73. }
  74. if (create) { it.root().value_ = {std::forward<Args>(args)...}; }
  75. return {std::move(it), create};
  76. }
  77. // n := total elements
  78. // d := average depth
  79. // Stack: O(1)
  80. // Operations: O(n)
  81. template <typename K, typename V, typename C> void trie<K, V, C>::clear() {
  82. for (reverse_iterator it = rbegin(), end = rend(); it != end && !it.empty();
  83. ++it) {
  84. auto ptr = std::move(it.current()->second);
  85. ptr->impl_.clear();
  86. }
  87. value_ = mapped_type{};
  88. impl_.clear();
  89. }
  90. template <typename K, typename V, typename C>
  91. void trie<K, V, C>::drop(iterator it) {
  92. if (it == end()) return;
  93. it.root().clear();
  94. if (!it.empty()) {
  95. auto to_erase = it.current().current();
  96. it.pop();
  97. it.root().impl_.erase(to_erase);
  98. }
  99. }
  100. namespace detail {
  101. template <typename Iter, typename Trie, typename KS>
  102. Iter find_impl(Trie * tr, KS const & keys) {
  103. Iter rval{tr};
  104. for (auto & key : keys) {
  105. auto & top = rval.root().impl_;
  106. auto it = top.find(key), end = top.end();
  107. if (it == end) { return {}; }
  108. rval.push({it, end});
  109. }
  110. return rval;
  111. }
  112. }