参考后台开发:核心技术
关于vector几个需要注意的点:
1.是比较器的写法
2.是迭代器失效的场景
(1)当删除该位置得迭代器得时候,实际上该迭代器就会失效了,这个时候实际上就变成了野指针了
(2),但是,与伴随 string 插入时迭代器失效的一般
规则一致,所有从插入位置到 string 结尾的迭代器 、 指针 、 引用将失效 。
3.在写成员函数的时候需要注意以下
当进行 insert 或 push_back 等增加元素的操作时,如果此时动态数组的内存不够用,就要动态的重新分配当前大小的 1.5 ~ 2 倍的新内存区,再把原数组的内容复制过去。
上次笔试差点都不会写比较器了...
typedef struct rect {
int id;
int length;
int width;
}Rect;
int cmp(const Rect& a, const Rect& b) {
if (a.id != b.id) {
return a.id < b.id;
}
else {
if (a.length != b.length) {
return a.length < b.length;
}
else
return a.width < b.width;
}
}
手写Vector容器
template<class T>
class MyVector {
private:
/*
这个实现与标准库的实现不太一样,标准库是使用三个指针来实现的
*/
unsigned int Size;
unsigned int Capacity;
T* array;
private:
T* allocator(unsigned int size) { return new T[size]; }
void deallocator(T* arr){
if (arr)
delete[] arr;
}
public:
//拷贝构造
MyVector():array(0),Size(0),Capacity(0){}
MyVector(const T& t, int n);
MyVector(const MyVector<T>& other);
MyVector& operator=(const MyVector<T>& other);
~MyVector();
T& operator[](unsigned int pos);
unsigned int size() { return Size; }
unsigned int capacity() { return Capacity; }
bool empty() { return Size == 0; }
void clear();
void push_back(const T& t);
void push_front(const T& t);
void pop_back();
void erase(insigned int pos);
void insert_before(int pos, const T& t);
void insert_after(int pos, const T& t);//最核心的函数
};
接下来是对这些方法的实现了
想一下实现手法,里面最核心的函数就是
insert_after了,其他函数都是基于它的,另外需要注意的一点是需要判断一些边界条件。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
template<class T>
class MyVector {
private:
/*
这个实现与标准库的实现不太一样,标准库是使用三个指针来实现的
*/
#define WALK_LENGTH 64
unsigned int Size;
unsigned int Capacity;
T* data;
private:
T* allocator(unsigned int size) { return new T[size]; }
void deallocator(T* arr){
if (arr)
delete[] arr;
}
public:
//拷贝构造
MyVector():data(0),Size(0),Capacity(0){}
MyVector(const T& t,unsigned int n):data(0),Size(0),Capacity(0) {
while (n--) {
push_back(t);
}
}
MyVector(const MyVector<T>& other):data(0),Size(0),Capacity(0) {
*this = other;
}
MyVector& operator=(const MyVector<T>& other) {
if (this == &other)
return *this;
clear();
Size = other.Size;
Capacity = other.Capacity;
data = new T[Capacity];
for (unsigned i = 0; i < Size; i++)
{
data[i] = other.data[i];
}
return *this;
}
~MyVector() {
clear();
}
T& operator[](unsigned int pos) {
return data[pos];
}
unsigned int size() { return Size; }
unsigned int capacity() { return Capacity; }
bool empty() { return Size == 0; }
void clear() {
deallocator(data);
data = 0;
Size = 0;
Capacity = 0;
}
void push_back(const T& t) { insert_after(Size - 1, t); }
void push_front(const T& t) { insert_before(0, t); }
void pop_back();
void erase(unsigned int pos);
void insert_before(int pos, const T& t);
void insert_after(int pos, const T& t);
};
template<typename T>
void MyVector<T>::erase(unsigned int pos) {
if (pos < Size) {
--Size;
for (int i = pos; i < Size; i++) {
data[i] = data[i + 1];
}
}
}
template<typename T>
void MyVector<T>::insert_after(int pos, const T& t) {
insert_before(pos + 1, t);
}
template <typename T>
void MyVector<T>::insert_before(int pos, const T& t) {
if (Size == Capacity) {
T* oldArray = data;
Capacity = Capacity + WALK_LENGTH;
data = allocator(Capacity);
memcpy(data, oldArray, Size * sizeof(T));
deallocator(oldArray);
}
for (int i = Size++; i > pos; --i) {
data[i] = data[i - 1];
}
data[pos] = t;
}
void printVector(MyVector<int>& vector1) {
for (unsigned int i = 0; i < vector1.size(); i++) {
cout << vector1[i] << ", ";
}
cout << "alloc size = " << vector1.capacity() << endl;
}
int main(){
MyVector<int> myVector1;
MyVector<int> myVector2(0, 10);
myVector2.push_front(1);
myVector2.erase(11);
printVector(myVector2);
myVector1.push_back(2);
myVector1.push_front(1);
printVector(myVector1);
myVector1.insert_after(1, 3);
printVector(myVector1);
myVector2 = myVector1;
myVector2.insert_before(0, 0);
myVector2.insert_before(1,-1);
printVector(myVector2);
return 0;
}