Преглед изворни кода

Make trie's copy constructor O(n)

Samuel Jaffe пре 8 година
родитељ
комит
993a2ca94e
3 измењених фајлова са 18 додато и 8 уклоњено
  1. 6 2
      trie.hpp
  2. 7 4
      trie_impl.hpp
  3. 5 2
      trie_iterator.hpp

+ 6 - 2
trie.hpp

@@ -96,8 +96,12 @@ public:
   void clear();
 private:
   friend bool operator==(trie const & lhs, trie const & rhs) {
-    auto it1 = lhs.begin(), it2 = rhs.begin(), end1 = lhs.end(), end2 = lhs.end();
-    for ( ; it1 != end1 && it2 != end2 && it1 == it2; ++it1, ++it2 );
+    if (lhs.value() != rhs.value()) { return false; }
+    auto it1 = ++lhs.begin(), it2 = ++rhs.begin(), end1 = lhs.end(), end2 = lhs.end();
+    for ( ; it1 != end1 && it2 != end2; ++it1, ++it2 ) {
+      if (it1.keys.back() != it2.keys.back()) { return false; }
+      else if (*it1 != *it2) { return false; }
+    }
     return it1 == end1 && it2 == end2;
   }
   friend void swap(trie & lhs, trie & rhs) {

+ 7 - 4
trie_impl.hpp

@@ -19,11 +19,14 @@ trie<K, V, C>::trie(mapped_type const & value)
 // n := total elements
 // d := average depth
 // Stack: O(1)
-// Operations: O(n*d)
+// Operations: O(n)
 template <typename K, typename V, typename C>
-trie<K, V, C>::trie(trie const & other) {
-  for (const_iterator it = other.begin(), end = other.end(); it != end; ++it) {
-    insert(it.keys, *it);
+trie<K, V, C>::trie(trie const & other) : value_(other.value_) {
+  iterator current{this};
+  for (const_iterator it = ++other.begin(), end = other.end(); it != end; ++it) {
+    while (current.keys.size() >= it.keys.size()) { current.pop(); }
+    auto tmp = current.stk.top()->insert(it.keys.back(), *it).first;
+    current.push(tmp.iters.top());
   }
 }
 

+ 5 - 2
trie_iterator.hpp

@@ -47,11 +47,14 @@ namespace detail {
       keys.push_back(it->first);
       stk.push(it->second.get());
     }
-    bool poping_empty() {
-      if (!iters.top().done()) { return false; }
+    void pop() {
       stk.pop();
       iters.pop();
       keys.pop_back();
+    }
+    bool poping_empty() {
+      if (!iters.top().done()) { return false; }
+      pop();
       return !iters.empty();
     }
     void assign() {