trie_impl.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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*d)
  18. template <typename K, typename V, typename C>
  19. trie<K, V, C>::trie(trie const & other) {
  20. for (const_iterator it = other.begin(), end = other.end(); it != end; ++it) {
  21. insert(it.keys, *it);
  22. }
  23. }
  24. template <typename K, typename V, typename C>
  25. trie<K, V, C>::~trie() {
  26. clear();
  27. }
  28. template <typename K, typename V, typename C>
  29. auto trie<K, V, C>::operator=(mapped_type const & value) -> self_t & {
  30. value_ = value;
  31. return *this;
  32. }
  33. template <typename K, typename V, typename C>
  34. auto trie<K, V, C>::operator=(trie const & other) -> self_t & {
  35. trie tmp{other};
  36. swap(*this, tmp);
  37. return *this;
  38. }
  39. // n := total elements
  40. // d := average depth
  41. // Operations: O(d*log(n/d))
  42. template <typename K, typename V, typename C>
  43. template <typename KS, typename>
  44. auto trie<K, V, C>::operator[](KS const & keys) -> self_t & {
  45. self_t * rec = this;
  46. for ( key_type const & key : keys ) {
  47. rec = &(*rec)[key];
  48. }
  49. return *rec;
  50. }
  51. // n := total elements
  52. // d := average depth
  53. // Operations: O(log(n))
  54. template <typename K, typename V, typename C>
  55. auto trie<K, V, C>::operator[](key_type const & key) -> self_t & {
  56. auto it = impl_.lower_bound(key);
  57. if ( it == impl_.end() || key_compare()(key, it->first) ) {
  58. it = impl_.emplace_hint(it, key, make_value<self_t>());
  59. }
  60. return *(it->second);
  61. }
  62. // n := total elements
  63. // d := average depth
  64. // Operations: O(d*log(n/d))
  65. template <typename K, typename V, typename C>
  66. auto trie<K, V, C>::operator[](std::initializer_list<key_type> keys) -> self_t & {
  67. self_t * rec = this;
  68. for ( key_type const & key : keys ) {
  69. rec = &(*rec)[key];
  70. }
  71. return *rec;
  72. }
  73. template <typename K, typename V, typename C>
  74. template <typename KS>
  75. auto trie<K, V, C>::insert(KS const & keys, mapped_type const & value) -> void {
  76. operator[](keys) = value;
  77. }
  78. template <typename K, typename V, typename C>
  79. auto trie<K, V, C>::insert(std::initializer_list<key_type> keys, mapped_type const & value) -> void {
  80. operator[](keys) = value;
  81. }
  82. template <typename K, typename V, typename C>
  83. auto trie<K, V, C>::insert(key_type const & key, mapped_type const & value) -> std::pair<iterator, bool> {
  84. auto it = impl_.lower_bound(key);
  85. if ( it == impl_.end() || key_compare()(key, it->first) ) {
  86. return { impl_.emplace_hint(it, key, make_value<self_t>(value)), true };
  87. // n := total elements
  88. // d := average depth
  89. // Stack: O(1)
  90. // Operations: O(n)
  91. template <typename K, typename V, typename C>
  92. void trie<K, V, C>::clear() {
  93. for (reverse_iterator it = rbegin(), end = rend(); it != end && !it.iters.empty(); ++it) {
  94. auto ptr = std::move(it.iters.top()->second);
  95. ptr->impl_.clear();
  96. }
  97. value_ = mapped_type{};
  98. impl_.clear();
  99. }