trie_impl.hpp 3.8 KB

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