Browse Source

添加删除方法erase, 修改文件类型名

ToiletMaster 10 months ago
parent
commit
4d2481ca35
5 changed files with 156 additions and 3 deletions
  1. 116 0
      analysis5.cpp
  2. 5 0
      list.h
  3. 18 0
      list.inl
  4. 3 1
      tire.h
  5. 14 2
      tire.inl

+ 116 - 0
analysis5.cpp

@@ -0,0 +1,116 @@
+#include <iostream>
+#include <string>
+#include <vector>
+#include <unordered_map>
+#include <chrono>
+using namespace std;
+
+#include "list.h"
+#include "tire.h"
+
+const int N = 1e5;
+const int M1 = 3;
+const int M2 = 5;
+
+struct Test {
+	int num;
+	string str;
+};
+
+vector<long long> umap_times;
+vector<long long> tire_times;
+
+void umap_test() {
+	unordered_map<string, Test> umap;
+	for (int i = 0; i < N; ++i) {
+		Test test;
+		test.num = i + 1;
+		test.str = to_string(i + 1);
+		umap.insert({ test.str, test });
+	};
+	auto start = chrono::high_resolution_clock::now();
+	size_t count = 0ull;
+	for (int i = N * 2; i >= 0; i -= 17) {
+		size_t res = umap.erase(to_string(i + 1));
+		count += res;
+	};
+	auto end = chrono::high_resolution_clock::now();
+	auto duration = chrono::duration_cast<chrono::microseconds>(end - start);
+	umap_times.push_back(duration.count());
+}
+
+void tire_test() {
+	Tire<Test> tire;
+	for (int i = 0; i < N; ++i) {
+		Test test;
+		test.num = i + 1;
+		test.str = to_string(i + 1);
+		tire.insert(test.str, test);
+	};
+	auto start = chrono::high_resolution_clock::now();
+	size_t count = 0ull;
+	for (int i = N * 2; i >= 0; i -= 17) {
+		size_t res = tire.erase(to_string(i + 1));
+		count += res;
+	};
+	auto end = chrono::high_resolution_clock::now();
+	auto duration = chrono::duration_cast<chrono::microseconds>(end - start);
+	tire_times.push_back(duration.count());
+}
+
+void analysis(string name, vector<long long>& nums) {
+	const int n = nums.size();
+	long long maxn = LLONG_MIN, minn = LLONG_MAX;
+	long long sum = 0;
+	for (long long& num : nums) {
+		maxn = max(maxn, num);
+		minn = min(minn, num);
+		sum += num;
+	}
+	cout << name << ": " << "maxn: " << maxn << "ms    " << "minn: " << minn << "ms    " << "avg: " << (1.0 * sum / n) << "ms    " << "sum: " << sum << "ms    " << endl;
+}
+
+void print_times(string name, vector<long long>& nums) {
+	cout << name << endl;
+	for (long long& num : nums) {
+		cout << num << " ";
+	};
+	cout << endl;
+}
+
+int main() {
+	// group 1
+	for (int i = 0; i < M1; ++i) {
+		umap_test();
+		tire_test();
+	}
+
+	// group 2
+	for (int i = 0; i < M1; ++i) {
+		tire_test();
+		umap_test();
+	}
+
+	// group 3
+	for (int i = 0; i < M2; ++i) {
+		umap_test();
+	}
+	for (int i = 0; i < M2; ++i) {
+		tire_test();
+	}
+
+	// group 4
+	for (int i = 0; i < M2; ++i) {
+		tire_test();
+	}
+	for (int i = 0; i < M2; ++i) {
+		umap_test();
+	}
+
+	// 分析
+	print_times("umap", umap_times);
+	print_times("tire", tire_times);
+	analysis("umap", umap_times);
+	analysis("tire", tire_times);
+	return 0;
+}

+ 5 - 0
list.h

@@ -1,6 +1,8 @@
 #ifndef __L87_LIST_H__
 #define __L87_LIST_H__
 
+#include <crtdefs.h>
+
 template<typename Type>
 class List {
 public:
@@ -35,6 +37,8 @@ private:
 public:
 	List();
 	~List();
+	size_t erase(Type& target);
+	void erase(Node* node);
 public:
 	iterator& operator[] (int index);
 	List& operator+= (Type& value);
@@ -46,5 +50,6 @@ public:
 	iterator rend();
 };
 
+#include "list.inl"
 
 #endif

+ 18 - 0
list.cpp → list.inl

@@ -45,6 +45,24 @@ TEMPLATE(HOLDER) ADT::~List() {
 	}
 }
 
+TEMPLATE(size_t) ADT::erase(Type& target) {
+	Node* curr = head->_next;
+	Node* next = nullptr;
+	for (; curr != &dummy;) {
+		if (curr->_value == target) {
+			erase(curr->value);
+			return (size_t)1ull;
+		}
+	}
+	return (size_t)0ull;
+}
+
+TEMPLATE(void) ADT::erase(Node* node) {
+	node->_prev->_next = node->_next;
+	node->_next->_prev = node->_prev;
+	delete node;
+}
+
 TEMPLATE(typename ITERATOR) ADT::begin() { return ADT::iterator(head->_next); }
 
 TEMPLATE(typename ITERATOR) ADT::end() { return ADT::iterator(head); }

+ 3 - 1
tire.h

@@ -32,7 +32,7 @@ template<typename Type,
 		Type& operator[](const std::string& key);
 		iterator find(const std::string& key);
 		iterator insert(const std::string& key, Type& value);
-		iterator erase(const std::string& key);
+		size_t erase(const std::string& key);
 	public:
 		iterator begin();
 		iterator end();
@@ -40,4 +40,6 @@ template<typename Type,
 		iterator rend();
 };
 
+#include "tire.inl"
+
 #endif

+ 14 - 2
tire.cpp → tire.inl

@@ -90,8 +90,20 @@ TEMPLATE(typename ITERATOR) ADT::insert(const std::string& key, Type& value) {
 	return it;
 }
 
-TEMPLATE(typename ITERATOR) ADT::erase(const std::string& key) {
-	return false; // TBD
+TEMPLATE(size_t) ADT::erase(const std::string& key) {
+	Node* curr = _root;
+	Node* next = nullptr;
+	for (const char& ch : key) {
+		next = curr->next[INDEX(ch)];
+		if (next == nullptr) {
+			return 0;
+		}
+		curr = next;
+	}
+	size_t res = curr->value == nullptr ? 0 : 1;
+	_container.erase(curr->value);
+	curr->value = nullptr;
+	return res;
 }
 
 TEMPLATE(typename ITERATOR) ADT::begin() { return _container.begin(); }