Browse Source

添加 "前缀子树获取方法"

ToiletMaster 10 months ago
parent
commit
aea023a3f3
2 changed files with 56 additions and 8 deletions
  1. 6 1
      tire.h
  2. 50 7
      tire.inl

+ 6 - 1
tire.h

@@ -18,10 +18,14 @@ template<typename Type,
 		};
 
 		typedef typename Container::iterator iterator;
-
 	private:
 		Node* _root = new Node();
 		Container _container;
+
+	private:
+		// 子树 (子树不支持迭代器, 且主树析构后子树不可用)
+		bool _is_subtree;
+		Tire(Node* root);
 	public:
 		Tire();
 		~Tire();
@@ -29,6 +33,7 @@ template<typename Type,
 		iterator find(const std::string& key);
 		iterator insert(const std::string& key, Type& value);
 		size_t erase(const std::string& key);
+		Tire& set_prefix(string& key);
 	public:
 		iterator begin();
 		iterator end();

+ 50 - 7
tire.inl

@@ -43,11 +43,18 @@ TEMPLATE(HOLDER) NODE::~Node() {
 
 // #pragma region Tire<Type>
 TEMPLATE(HOLDER) ADT::Tire() {
+	_is_subtree = false;
+}
 
+TEMPLATE(HOLDER) ADT::Tire(Node* root) {
+	_root = root;
+	_is_subtree = true;
 }
 
 TEMPLATE(HOLDER) ADT::~Tire() {
-	delete _root;
+	if (_is_subtree == false) {
+		delete _root;
+	}
 }
 
 TEMPLATE(typename ITERATOR) ADT::find(const std::string& key) {
@@ -137,17 +144,53 @@ TEMPLATE(size_t) ADT::erase(const std::string& key) {
 			curr = next;
 		}
 	}
-	size_t res = curr->value == nullptr ? 0 : 1;
-	_container.erase(curr->value);
-	curr->value = nullptr;
-	return res;
+	if (curr->value == nullptr) {
+		return 0;
+	}
+	else {
+		_container.erase(curr->value);
+		curr->value = nullptr;
+		return 1;
+	}
+}
+
+TEMPLATE(ADT&) ADT::set_prefix(string& key) {
+	Node* curr = _root;
+	Node* next = nullptr;
+	for (const char& ch : key) {
+		{
+			// 高 4 位
+			unsigned int h = ((unsigned char)ch >> 4) & 0x0fu;
+			next = curr->next[h];
+			if (next == nullptr) {
+				curr->bitmap |= 0x01u << h;
+				curr = curr->next[h] = new Node();
+			}
+			else {
+				curr = next;
+			}
+		}
+		{
+			// 低 4 位
+			unsigned int l = ch & 0x0fu;
+			next = curr->next[l];
+			if (next == nullptr) {
+				curr->bitmap |= 0x01u << l;
+				curr = curr->next[l] = new Node();
+			}
+			else {
+				curr = next;
+			}
+		}
+	}
+	return Tire(curr);
 }
 
-TEMPLATE(typename ITERATOR) ADT::begin() { return _container.begin(); }
+TEMPLATE(typename ITERATOR) ADT::begin() { return _is_subtree == false ? _container.begin() : _container.end(); }
 
 TEMPLATE(typename ITERATOR) ADT::end() { return _container.end(); }
 
-TEMPLATE(typename ITERATOR) ADT::rbegin() { return _container.rbegin(); }
+TEMPLATE(typename ITERATOR) ADT::rbegin() { return _is_subtree == false ? _container.rbegin() : _container.rend(); }
 
 TEMPLATE(typename ITERATOR) ADT::rend() { return _container.rend(); }