diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..29e1aea --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,57 @@ +{ + "files.associations": { + "*.lsp": "lua", + "deque": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "format": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "span": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "text_encoding": "cpp", + "typeinfo": "cpp", + "variant": "cpp", + "cassert": "cpp" + }, + "Codegeex.RepoIndex": true +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..6f3c8cc --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: g++.exe 生成活动文件", + "command": "e:\\mingw64\\bin\\g++.exe", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}\\${fileBasenameNoExtension}.exe" + ], + "options": { + "cwd": "e:\\mingw64\\bin" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "调试器生成的任务。" + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..e69de29 diff --git a/mySTL/container.h b/mySTL/container.h new file mode 100644 index 0000000..cbcda6a --- /dev/null +++ b/mySTL/container.h @@ -0,0 +1,31 @@ +#ifndef CONTAINER_H +#define CONTAINER_H + +#include + +template +class Container { +public: + virtual ~Container() = default; + + // 添加元素 + virtual void push(const T& value) = 0; + + // 移除元素 + virtual void pop() = 0; + + // 访问顶部元素 + virtual T& top() = 0; + virtual const T& top() const = 0; + + // 检查容器是否为空 + virtual bool empty() const = 0; + + // 返回容器中的元素数量 + virtual size_t size() const = 0; + + // 清空容器 + virtual void clear() = 0; +}; + +#endif // CONTAINER_H diff --git a/mySTL/my_deque.h b/mySTL/my_deque.h new file mode 100644 index 0000000..c7341dd --- /dev/null +++ b/mySTL/my_deque.h @@ -0,0 +1,213 @@ +#ifndef MY_DEQUE_H +#define MY_DEQUE_H + +#include "container.h" +#include +#include + +template +class MyDeque : public Container { +private: + static const size_t CHUNK_SIZE = 8; // 每个块的大小 + + T** map; // 中控器 + size_t map_capacity; // 中控器容量 + size_t start_chunk; // 起始块索引 + size_t start_pos; // 起始块中的位置 + size_t size_; + + void initialize_map(size_t n) { + map_capacity = std::max(size_t(8), n / CHUNK_SIZE + 1); + map = new T*[map_capacity]; + for (size_t i = 0; i < map_capacity; i++) { + map[i] = new T[CHUNK_SIZE]; + } + start_chunk = map_capacity / 2; + start_pos = CHUNK_SIZE / 2; + size_ = 0; + } + + void ensure_capacity(size_t needed_chunks) { + if (needed_chunks > map_capacity) { + size_t new_capacity = map_capacity * 2; + T** new_map = new T*[new_capacity]; + + size_t new_start = (new_capacity - needed_chunks) / 2; + for (size_t i = 0; i < map_capacity; i++) { + new_map[new_start + i] = map[i]; + } + + for (size_t i = 0; i < new_start; i++) { + new_map[i] = new T[CHUNK_SIZE]; + } + for (size_t i = new_start + map_capacity; i < new_capacity; i++) { + new_map[i] = new T[CHUNK_SIZE]; + } + + delete[] map; + map = new_map; + start_chunk = new_start; + map_capacity = new_capacity; + } else if (needed_chunks < map_capacity / 4 && needed_chunks >= 0) { + size_t new_capacity = map_capacity / 2; + T** new_map = new T*[new_capacity]; + + size_t new_start = (new_capacity - needed_chunks) / 2; + for (size_t i = 0; i < needed_chunks; i++) { + new_map[new_start + i] = map[start_chunk + i]; + } + + for(size_t i = 0; i < new_start; i++) { + new_map[i] = new T[CHUNK_SIZE]; + } + for (size_t i = new_start + needed_chunks; i < new_capacity; i++) { + new_map[i] = new T[CHUNK_SIZE]; + } + + for(size_t i = 0; i < start_chunk; i++) { + delete[] map[i]; + } + for(size_t i = start_chunk + needed_chunks; i < map_capacity; i++) { + delete[] map[i]; + } + + delete[] map; + map = new_map; + start_chunk = new_start; + map_capacity = new_capacity; + } + } + +public: + MyDeque() { + initialize_map(0); + } + + ~MyDeque() { + for (size_t i = 0; i < map_capacity; i++) { + delete[] map[i]; + } + delete[] map; + } + + void push_back(const T& value) { + size_t end_chunk = (start_chunk + (start_pos + size_) / CHUNK_SIZE); + size_t end_pos = (start_pos + size_) % CHUNK_SIZE; + + if (end_chunk >= map_capacity) { + ensure_capacity(end_chunk + 1); + } + + map[end_chunk][end_pos] = value; + size_++; + } + + T& back() { + if (empty()) { + throw std::out_of_range("back of empty deque"); + } + size_t end_chunk = (start_chunk + (start_pos + size_ - 1) / CHUNK_SIZE); + size_t end_pos = (start_pos + size_ - 1) % CHUNK_SIZE; + return map[end_chunk][end_pos]; + } + + const T& back() const { + if (empty()) { + throw std::out_of_range("back of empty deque"); + } + size_t end_chunk = (start_chunk + (start_pos + size_ - 1) / CHUNK_SIZE); + size_t end_pos = (start_pos + size_ - 1) % CHUNK_SIZE; + return map[end_chunk][end_pos]; + } + + void pop_back() { + if (empty()) { + throw std::out_of_range("pop_back from empty deque"); + } + size_--; + if((start_pos + size_ ) / CHUNK_SIZE + 1< map_capacity / 4) { + ensure_capacity((start_pos + size_) / CHUNK_SIZE + 1); + } + } + + void push_front(const T& value) { + if (start_pos == 0) { + if (start_chunk == 0) { + ensure_capacity(map_capacity + 1); + } + start_chunk--; + start_pos = CHUNK_SIZE; + } + start_pos--; + map[start_chunk][start_pos] = value; + size_++; + } + + T& front() { + if (empty()) { + throw std::out_of_range("front of empty deque"); + } + return map[start_chunk][start_pos]; + } + + const T& front() const { + if (empty()) { + throw std::out_of_range("front of empty deque"); + } + return map[start_chunk][start_pos]; + } + + void pop_front() { + if (empty()) { + throw std::out_of_range("pop_front from empty deque"); + } + start_pos++; + if (start_pos == CHUNK_SIZE) { + start_chunk++; + start_pos = 0; + } + size_--; + if((start_pos + size_ ) / CHUNK_SIZE + 1< map_capacity / 4) { + ensure_capacity((start_pos + size_) / CHUNK_SIZE + 1); + } + } + + T& operator[](size_t n) { + size_t chunk = start_chunk + (start_pos + n) / CHUNK_SIZE; + size_t pos = (start_pos + n) % CHUNK_SIZE; + return map[chunk][pos]; + } + + void push(const T& value) override { + push_front(value); + } + + void pop() override { + pop_front(); + } + + T& top() override { + return front(); + } + + const T& top() const override { + return front(); + } + + bool empty() const override { + return size_ == 0; + } + + size_t size() const override { + return size_; + } + + void clear() override { + size_ = 0; + start_chunk = 0; + start_pos = 0; + ensure_capacity(0); + } +}; + +#endif \ No newline at end of file diff --git a/mySTL/my_deque_test.cpp b/mySTL/my_deque_test.cpp new file mode 100644 index 0000000..e08fee9 --- /dev/null +++ b/mySTL/my_deque_test.cpp @@ -0,0 +1,43 @@ +#include "my_deque.h" +#include + +int main() { + // 测试默认构造函数 + MyDeque dq; + assert(dq.empty()); + assert(dq.size() == 0); + + // 测试 push_back 和 back + dq.push_back(1); + assert(dq.back() == 1); + assert(dq.size() == 1); + + // 测试 push_front 和 front + dq.push_front(2); + assert(dq.front() == 2); + assert(dq.size() == 2); + + // 测试 pop_back + dq.pop_back(); + assert(dq.front() == 2); + assert(dq.size() == 1); + + // 测试 pop_front + dq.pop_front(); + assert(dq.empty()); + assert(dq.size() == 0); + + // 测试 operator[] + dq.push_back(3); + dq.push_back(4); + assert(dq[0] == 3); + assert(dq[1] == 4); + + // 测试 clear + dq.clear(); + assert(dq.empty()); + assert(dq.size() == 0); + + printf("All tests passed!\n"); + return 0; +} diff --git a/mySTL/my_list.h b/mySTL/my_list.h new file mode 100644 index 0000000..85820ea --- /dev/null +++ b/mySTL/my_list.h @@ -0,0 +1,266 @@ +#ifndef MY_LIST_H +#define MY_LIST_H + +#include "container.h" +#include +#include + +template +class MyList : public Container { +private: + struct Node { + T data; + Node* prev; + Node* next; + Node(const T& value, Node* p = nullptr, Node* n = nullptr) + : data(value), prev(p), next(n) {} + }; + + Node* head; // 指向链表头部 + Node* tail; // 指向链表尾部 + size_t size_; + +public: + MyList() : head(nullptr), tail(nullptr), size_(0) {} + + ~MyList() override { + clear(); + } + + void push_back(const T& value) { + Node* new_node = new Node(value); + if (tail == nullptr) { + head = tail = new_node; + } else { + tail->next = new_node; + new_node->prev = tail; + tail = new_node; + } + size_++; + } + + void push_front(const T& value) { + Node* new_node = new Node(value, nullptr, head); + if (head == nullptr) { + head = tail = new_node; + } else { + head->prev = new_node; + head = new_node; + } + size_++; + } + + void pop_back() { + if (empty()) { + throw std::out_of_range("pop from empty list"); + } + Node* to_delete = tail; + tail = tail->prev; + if (tail) { + tail->next = nullptr; + } else { + head = nullptr; + } + delete to_delete; + size_--; + } + + void pop_front() { + if (empty()) { + throw std::out_of_range("pop_front from empty list"); + } + Node* to_delete = head; + head = head->next; + if (head) { + head->prev = nullptr; + } else { + tail = nullptr; + } + delete to_delete; + size_--; + } + + void insert(size_t index, const T& value) { + if (index > size_) { + throw std::out_of_range("index out of range"); + } + if (index == 0) { + push_front(value); + } else if (index == size_) { + push_back(value); + } else { + Node* new_node = new Node(value); + Node* current = head; + for (size_t i = 0; i < index - 1; i++) { + current = current->next; + } + new_node->prev = current; + new_node->next = current->next; + current->next->prev = new_node; + current->next = new_node; + size_++; + } + } + + void erase(size_t index) { + if (index >= size_) { + throw std::out_of_range("index out of range"); + } + if (index == 0) { + pop_front(); + } else if (index == size_ - 1) { + pop_back(); + } else { + Node* to_delete = head; + for (size_t i = 0; i < index; i++) { + to_delete = to_delete->next; + } + to_delete->prev->next = to_delete->next; + if (to_delete->next) { + to_delete->next->prev = to_delete->prev; + } + delete to_delete; + size_--; + } + } + + T& back() { + if (empty()) { + throw std::out_of_range("top of empty list"); + } + return tail->data; + } + + const T& back() const { + if (empty()) { + throw std::out_of_range("top of empty list"); + } + return tail->data; + } + + T& front() { + if (empty()) { + throw std::out_of_range("front of empty list"); + } + return head->data; + } + + const T& front() const { + if (empty()) { + throw std::out_of_range("front of empty list"); + } + return head->data; + } + + class iterator { + private: + Node* node; + + public: + iterator(Node* n = nullptr) : node(n) {} + + iterator& operator++() { // 前缀++ + if (node) node = node->next; + return *this; + } + + iterator operator++(int) { // 后缀++ + iterator iterator = *this; + ++(*this); + return iterator; + } + + iterator& operator--() { // 前缀-- + if (node) node = node->prev; + return *this; + } + + iterator operator--(int) { // 后缀-- + iterator iterator = *this; + --(*this); + return iterator; + } + + bool operator==(const iterator& other) const { + return node == other.node; + } + + bool operator!=(const iterator& other) const { + return node != other.node; + } + + T& operator*() { + return node->data; + } + + const T& operator*() const { + return node->data; + } + + T* operator->() { + return &(node->data); + } + + const T* operator->() const { + return &(node->data); + } + + Node * get_node() const { + return node; + } + }; + + // 提供begin和end方法来返回迭代器 + iterator begin() { + return iterator(head); + } + + iterator end() { + return iterator(nullptr); + } + + void erase(iterator ite) { + if (ite.get_node() == nullptr) { + throw std::out_of_range("index out of range"); + } + Node* to_delete = ite.get_node(); + to_delete->prev->next = to_delete->next; + if (to_delete->next) { + to_delete->next->prev = to_delete->prev; + } + delete to_delete; + size_--; + } + + void push(const T& value) override { + push_back(value); + } + + void pop() override { + pop_back(); + } + + T& top() override { + return back(); + } + + const T& top() const override { + return back(); + } + + bool empty() const override { + return size_ == 0; + } + + size_t size() const override { + return size_; + } + + void clear() override { + while(!empty()) { + pop_back(); + } + } +}; + +#endif diff --git a/mySTL/my_list_test.cpp b/mySTL/my_list_test.cpp new file mode 100644 index 0000000..9a993eb --- /dev/null +++ b/mySTL/my_list_test.cpp @@ -0,0 +1,42 @@ +#include "my_deque.h" +#include + +int main() { + // 测试默认构造函数 + MyDeque dq; + assert(dq.empty()); + assert(dq.size() == 0); + + // 测试 push_back 和 back + dq.push_back(1); + assert(dq.back() == 1); + assert(dq.size() == 1); + + // 测试 push_front 和 front + dq.push_front(2); + assert(dq.front() == 2); + assert(dq.size() == 2); + + // 测试 pop_back + dq.pop_back(); + assert(dq.front() == 2); + assert(dq.size() == 1); + + // 测试 pop_front + dq.pop_front(); + assert(dq.empty()); + assert(dq.size() == 0); + + // 测试 operator[] + dq.push_back(3); + dq.push_back(4); + assert(dq[0] == 3); + assert(dq[1] == 4); + + // 测试 clear + dq.clear(); + assert(dq.empty()); + assert(dq.size() == 0); + + return 0; +} diff --git a/mySTL/my_skiplist.h b/mySTL/my_skiplist.h new file mode 100644 index 0000000..e0944b6 --- /dev/null +++ b/mySTL/my_skiplist.h @@ -0,0 +1,148 @@ +#include +#include +#include "my_vector.h" +#include + +template +class SkipList { +private: + struct Node { + K key; + V value; + std::vector forward; // 存储每一层的前向指针 + + Node(K k, V v, int level) + : key(k), value(v), forward(level, nullptr) {} + }; + + Node* head; // 头节点 + int maxLevel; // 最大层数 + int currentLevel; // 当前层数 + float probability; // 生成上层节点的概率 + + // 生成随机层数 + int randomLevel() { + int level = 1; + while ((float)rand()/RAND_MAX < probability && level < maxLevel) { + level++; + } + return level; + } + +public: + SkipList(int maxLvl = 16, float p = 0.5) + : maxLevel(maxLvl), probability(p), currentLevel(1) { + K minKey = std::numeric_limits::min(); + head = new Node(minKey, V(), maxLevel); + } + + void insert(K key, V value) { + MyVector update(maxLevel, nullptr); + Node* current = head; + + for (int i = currentLevel - 1; i >= 0; i--) { + while (current->forward[i] != nullptr && + current->forward[i]->key < key) { + current = current->forward[i]; + } + update[i] = current; + } + + current = current->forward[0]; + + if (current != nullptr && current->key == key) { + current->value = value; + return; + } + + int newLevel = randomLevel(); + + if (newLevel > currentLevel) { + for (int i = currentLevel; i < newLevel; i++) { + update[i] = head; + } + currentLevel = newLevel; + } + + Node* newNode = new Node(key, value, newLevel); + + for (int i = 0; i < newLevel; i++) { + newNode->forward[i] = update[i]->forward[i]; + update[i]->forward[i] = newNode; + } + } + + bool find(K key, V& value) { + Node* current = head; + + for (int i = currentLevel - 1; i >= 0; i--) { + while (current->forward[i] != nullptr && + current->forward[i]->key < key) { + current = current->forward[i]; + } + } + + current = current->forward[0]; + + if (current != nullptr && current->key == key) { + value = current->value; + return true; + } + return false; + } + + bool erase(K key) { + MyVector update(maxLevel, nullptr); + Node* current = head; + + for (int i = currentLevel - 1; i >= 0; i--) { + while (current->forward[i] != nullptr && + current->forward[i]->key < key) { + current = current->forward[i]; + } + update[i] = current; + } + + current = current->forward[0]; + + if (current == nullptr || current->key != key) { + return false; + } + + for (int i = 0; i < currentLevel; i++) { + if (update[i]->forward[i] != current) { + break; + } + update[i]->forward[i] = current->forward[i]; + } + + delete current; + + while (currentLevel > 1 && head->forward[currentLevel - 1] == nullptr) { + currentLevel--; + } + + return true; + } + + void display() { + for (int i = currentLevel - 1; i >= 0; i--) { + Node* current = head->forward[i]; + std::cout << "Level " << i << ": "; + while (current != nullptr) { + std::cout << current->key << ":" << current->value << " "; + current = current->forward[i]; + } + std::cout << std::endl; + } + } + + ~SkipList() { + Node* current = head; + while (current != nullptr) { + Node* next = current->forward[0]; + delete current; + current = next; + } + } +}; \ No newline at end of file diff --git a/mySTL/my_skiplist_test.cpp b/mySTL/my_skiplist_test.cpp new file mode 100644 index 0000000..eccf8d8 --- /dev/null +++ b/mySTL/my_skiplist_test.cpp @@ -0,0 +1,33 @@ +#include "my_skiplist.h" +#include + +int main() { + // 测试默认构造函数 + SkipList skipList; + + // 测试 insert 和 find + skipList.insert(1, "one"); + std::string value; + assert(skipList.find(1, value) && value == "one"); + + // 测试 erase + assert(skipList.erase(1)); + assert(!skipList.find(1, value)); + + // 测试多个插入和查找 + skipList.insert(2, "two"); + skipList.insert(3, "three"); + skipList.insert(4, "four"); + assert(skipList.find(2, value) && value == "two"); + assert(skipList.find(3, value) && value == "three"); + assert(skipList.find(4, value) && value == "four"); + + // 测试 erase + assert(skipList.erase(3)); + assert(!skipList.find(3, value)); + + // 测试 display (不进行断言,只是输出当前跳表结构) + // skipList.display(); + + return 0; +} diff --git a/mySTL/my_stack.h b/mySTL/my_stack.h new file mode 100644 index 0000000..6623541 --- /dev/null +++ b/mySTL/my_stack.h @@ -0,0 +1,44 @@ +#ifndef MY_STACK_H +#define MY_STACK_H + +#include "container.h" +#include "my_vector.h" +#include "my_deque.h" +#include "my_list.h" + +//注意这里Container为模版参数,将具体的stack实现定义为MyVector +template > +class MyStack : public Container { +public: + void push(const T& value) { + Container::push(value); //用MyVector的push + } + + void pop() { + if (!this->empty()) { + Container::pop(); + } + } + + T& top() { + return Container::top(); + } + + const T& top() const { + return Container::top(); + } + + bool empty() const { + return Container::empty(); + } + + size_t size() const { + return Container::size(); + } + + void clear() { + Container::clear(); + } +}; + +#endif // MY_STACK_H diff --git a/mySTL/my_stack_test.cpp b/mySTL/my_stack_test.cpp new file mode 100644 index 0000000..3bf7c55 --- /dev/null +++ b/mySTL/my_stack_test.cpp @@ -0,0 +1,38 @@ +#include "my_stack.h" +#include + +int main() { + // 测试默认构造函数 + MyStack stack; + assert(stack.empty()); + assert(stack.size() == 0); + + // 测试 push 和 top + stack.push(1); + assert(stack.top() == 1); + assert(stack.size() == 1); + + // 测试 push 和 pop + stack.push(2); + stack.pop(); + assert(stack.top() == 1); + assert(stack.size() == 1); + + // 测试 clear + stack.clear(); + assert(stack.empty()); + assert(stack.size() == 0); + + // 测试多个 push 和 pop + stack.push(3); + stack.push(4); + stack.push(5); + assert(stack.top() == 5); + stack.pop(); + assert(stack.top() == 4); + stack.pop(); + assert(stack.top() == 3); + assert(stack.size() == 1); + + return 0; +} diff --git a/mySTL/my_vector.h b/mySTL/my_vector.h new file mode 100644 index 0000000..ba8abf5 --- /dev/null +++ b/mySTL/my_vector.h @@ -0,0 +1,168 @@ +#ifndef MY_VECTOR_H +#define MY_VECTOR_H + +#include "container.h" +#include +#include + +template +class MyVector : public Container {//继承 +private: + T* m_data; + size_t m_size; + size_t m_capacity; + + void reallocate(size_t new_capacity) { + T* new_data = new T[new_capacity]; + size_t copy_size = std::min(m_size, new_capacity); + for (size_t i = 0; i < copy_size; ++i) { + new_data[i] = std::move(m_data[i]); + } + delete[] m_data; + m_data = new_data; + m_capacity = new_capacity; + } + +public: + MyVector() : m_data(nullptr), m_size(0), m_capacity(0) {} + + explicit MyVector(size_t count, const T& value = T()) : m_size(count), m_capacity(count) { + m_data = new T[count]; + std::fill_n(m_data, count, value); + } + + MyVector(const MyVector& other) : m_size(other.m_size), m_capacity(other.m_capacity) { + m_data = new T[m_capacity]; + std::copy(other.m_data, other.m_data + m_size, m_data); + } + + MyVector(MyVector&& other) noexcept : m_data(other.m_data), m_size(other.m_size), m_capacity(other.m_capacity) { + other.m_data = nullptr; + other.m_size = other.m_capacity = 0; + } + + ~MyVector() override { + delete[] m_data; + } + + MyVector& operator=(const MyVector& other) { + if (this != &other) { + MyVector tmp(other); + std::swap(m_data, tmp.m_data); + std::swap(m_size, tmp.m_size); + std::swap(m_capacity, tmp.m_capacity); + } + return *this; + } + + MyVector& operator=(MyVector&& other) noexcept { + if (this != &other) { + delete[] m_data; + m_data = other.m_data; + m_size = other.m_size; + m_capacity = other.m_capacity; + other.m_data = nullptr; + other.m_size = other.m_capacity = 0; + } + return *this; + } + + void push(const T& value) override { + push_back(value); //具体函数的实现如下 + } + + void push_back(const T& value) { + if (m_size == m_capacity) { + reallocate(m_capacity == 0 ? 1 : m_capacity * 2); + } + m_data[m_size++] = value; + } + + void pop() override { + pop_back(); //具体函数的实现如下 + } + + void pop_back() { + if (!empty()) { + --m_size; + } + } + + T& top() override { + return back(); + } + + const T& top() const override { + return back(); + } + + T& back() { + if (empty()) { + throw std::out_of_range("Vector is empty"); + } + return m_data[m_size - 1]; + } + + const T& back() const { + if (empty()) { + throw std::out_of_range("Vector is empty"); + } + return m_data[m_size - 1]; + } + + bool empty() const override { + return m_size == 0; + } + + size_t size() const override { + return m_size; + } + + size_t capacity() const { + return m_capacity; + } + + void clear() override { + m_size = 0; + } + + void reserve(size_t new_capacity) { + if (new_capacity > m_capacity) { + reallocate(new_capacity); + } + } + + void resize(size_t new_size, const T& value = T()) { + if (new_size > m_capacity) { + reallocate(new_size); + } + if (new_size > m_size) { + std::fill(m_data + m_size, m_data + new_size, value); + } + m_size = new_size; + } + + T& operator[](size_t index) { + return m_data[index]; + } + + const T& operator[](size_t index) const { + return m_data[index]; + } + + T& at(size_t index) { + if (index >= m_size) { + throw std::out_of_range("Index out of range"); + } + return m_data[index]; + } + + const T& at(size_t index) const { + if (index >= m_size) { + throw std::out_of_range("Index out of range"); + } + return m_data[index]; + } +}; + +#endif // MY_VECTOR_H diff --git a/mySTL/my_vector_test.cpp b/mySTL/my_vector_test.cpp new file mode 100644 index 0000000..2f4584d --- /dev/null +++ b/mySTL/my_vector_test.cpp @@ -0,0 +1,66 @@ +#include "my_vector.h" +#include + +int main() { + // 测试默认构造函数 + MyVector vec1; + assert(vec1.size() == 0); + assert(vec1.capacity() == 0); + + // 测试带参数的构造函数 + MyVector vec2(5, 2); + assert(vec2.size() == 5); + assert(vec2.capacity() == 5); + for (size_t i = 0; i < vec2.size(); ++i) { + assert(vec2[i] == 2); + } + + // 测试 push_back 和 size + vec1.push_back(1); + vec1.push_back(2); + vec1.push_back(3); + assert(vec1.size() == 3); + + // 测试 pop_back 和 size + vec1.pop_back(); + assert(vec1.size() == 2); + + // 测试 back + assert(vec1.back() == 2); + + // 测试 clear + vec1.clear(); + assert(vec1.size() == 0); + + // 测试 reserve + vec1.reserve(10); + assert(vec1.capacity() == 10); + + // 测试 resize + vec1.resize(5, 3); + assert(vec1.size() == 5); + for (size_t i = 0; i < vec1.size(); ++i) { + assert(vec1[i] == 3); + } + + // 测试 operator[] + vec1[0] = 4; + assert(vec1[0] == 4); + + // 测试 at + assert(vec1.at(0) == 4); + + // 测试 copy assignment + MyVector vec3 = vec1; + assert(vec3.size() == vec1.size()); + for (size_t i = 0; i < vec3.size(); ++i) { + assert(vec3[i] == vec1[i]); + } + + // 测试 move assignment + MyVector vec4 = std::move(vec3); + assert(vec4.size() == 5); + assert(vec3.size() == 0); + + return 0; +}