trie_impl.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. iterator current{this};
  17. for (const_iterator it = ++other.begin(), end = other.end(); it != end; ++it) {
  18. while (current.keys.size() >= it.keys.size()) { current.pop(); }
  19. auto tmp = current.stk.top()->insert(it.keys.back(), *it).first;
  20. current.push(tmp.iters.top());
  21. }
  22. }
  23. template <typename K, typename V, typename C>
  24. auto trie<K, V, C>::operator=(mapped_type const & value) -> self_t & {
  25. value_ = value;
  26. return *this;
  27. }
  28. template <typename K, typename V, typename C>
  29. auto trie<K, V, C>::operator=(trie const & other) -> self_t & {
  30. trie tmp{other};
  31. swap(*this, tmp);
  32. return *this;
  33. }
  34. template <typename K, typename V, typename C>
  35. auto trie<K, V, C>::operator=(trie && other) -> self_t & {
  36. swap(*this, other);
  37. return *this;
  38. }
  39. // n := total elements
  40. // d := average depth
  41. // Operations: O(log(n)/d)
  42. template <typename K, typename V, typename C>
  43. template <typename... Args>
  44. void trie<K, V, C>::insert_impl(std::pair<iterator, bool> & out, key_type const & key, Args &&... args) {
  45. auto it = impl_.lower_bound(key);
  46. if ( it == impl_.end() || key_compare()(key, it->first) ) {
  47. out.second = true;
  48. it = impl_.emplace_hint(it, key, make_value<self_t>(std::forward<Args>(args)...));
  49. }
  50. out.first.push(make_end_aware_iterator(it, impl_.end()));
  51. }
  52. // n := total elements
  53. // d := average depth
  54. // Operations: O(log(n))
  55. template <typename K, typename V, typename C>
  56. template <typename KS>
  57. auto trie<K, V, C>::insert(KS const & keys, mapped_type const & value) -> std::pair<iterator, bool> {
  58. std::pair<iterator, bool> rval{this, false};
  59. for ( key_type const & key : keys ) {
  60. rval.first.stk.top()->insert_impl(rval, key);
  61. }
  62. if (rval.second) { *rval.first.stk.top() = value; }
  63. return rval;
  64. }
  65. // n := total elements
  66. // d := average depth
  67. // Operations: O(log(n))
  68. template <typename K, typename V, typename C>
  69. template <typename KS, typename... Args>
  70. auto trie<K, V, C>::emplace(KS const & keys, Args &&... args) -> std::pair<iterator, bool> {
  71. std::pair<iterator, bool> rval{this, false};
  72. for ( key_type const & key : keys ) {
  73. rval.first.stk.top()->insert_impl(rval, key);
  74. }
  75. if (rval.second) { rval.first.stk.top()->value() = {std::forward<Args>(args)...}; }
  76. return rval;
  77. }
  78. template <typename K, typename V, typename C>
  79. template <typename KS>
  80. auto trie<K, V, C>::find(KS const & keys) -> iterator {
  81. iterator rval{this};
  82. for (auto & key : keys) {
  83. auto & top = rval.stk.top()->impl_;
  84. auto it = top.find(key), end = top.end();
  85. if ( it == end ) { return {}; }
  86. rval.push({it, end});
  87. }
  88. return rval;
  89. }
  90. template <typename K, typename V, typename C>
  91. auto trie<K, V, C>::find(key_type const & key) -> iterator {
  92. auto it = impl_.find(key), end = impl_.end();
  93. if ( it == end ) { return {}; }
  94. iterator rval{this};
  95. rval.push({it, end});
  96. return rval;
  97. }
  98. // n := total elements
  99. // d := average depth
  100. // Stack: O(1)
  101. // Operations: O(n)
  102. template <typename K, typename V, typename C>
  103. void trie<K, V, C>::clear() {
  104. for (reverse_iterator it = rbegin(), end = rend(); it != end && !it.iters.empty(); ++it) {
  105. auto ptr = std::move(it.iters.top()->second);
  106. ptr->impl_.clear();
  107. }
  108. value_ = mapped_type{};
  109. impl_.clear();
  110. }
  111. template <typename K, typename V, typename C>
  112. void trie<K, V, C>::drop(iterator it) {
  113. if (it == end()) return;
  114. it.stk.top()->clear();
  115. if (!it.iters.empty()) {
  116. auto to_erase = it.iters.top().current();
  117. it.pop();
  118. it.stk.top()->impl_.erase(to_erase);
  119. }
  120. }