vector 是 C++ 标准库中的一个容器类模板,提供了动态数组的功能。它能够在运行时根据需要自动调整大小,并且支持快速的随机访问。
vector 的特点包括:
- 动态大小: vector 能够自动调整大小以容纳存储的元素。当元素数量增加时,vector 会自动分配更多的内存空间来容纳新的元素。
- 连续存储: vector 使用连续的内存块存储元素,因此可以通过指针算术运算来实现快速的随机访问。
- 快速插入和删除: 在 vector 的末尾插入或删除元素的操作具有较低的时间复杂度。然而,在中间位置插入或删除元素需要移动后续元素的成本较高。
- 随机访问: 可以通过索引来直接访问 vector 中的元素,而不需要遍历整个容器。
- 迭代器支持: vector 提供了迭代器来遍历容器中的元素,包括正向迭代器和反向迭代器。
- 内存管理: vector 负责管理存储元素的内存,可以自动分配和释放内存。
- 使用 vector 可以方便地存储和操作一组元素,它提供了许多成员函数和操作符重载来实现元素的插入、删除、访问和修改等操作。由于 vector 是一个模板类,可以存储任意类型的对象,包括内置类型和自定义类型。
为了实现了一个简化版的动态数组类 vector,我们需要进行以下操作:
首先,定义一个 vector 类,并声明了一些成员函数和类型别名。其中 iterator 表示迭代器类型,begin() 和 end() 函数分别返回指向容器起始和结束位置的迭代器。
然后,类中的私有成员变量包括 _start、_finish 和 _endofstorage,它们分别表示指向容器起始位置、结束位置和分配的内存结束位置的迭代器。
接下来,实现构造函数、拷贝构造函数和范围构造函数,用于创建 vector 对象。构造函数可以接受不同的参数形式,包括空构造、拷贝构造和范围构造。
然后,还需要实现一些其他的成员函数:
如 swap() 函数用于交换两个 vector 对象的内容,
operator= 重载函数用于实现赋值操作,
push_back() 函数用于在容器末尾添加元素,
capacity() 函数用于获取容器的容量,
size() 函数用于获取容器的大小,
reserve() 函数用于调整容器的容量,
resize() 函数用于调整容器的大小,并可以指定默认值,
insert() 函数用于在指定位置插入元素,
erase() 函数用于删除指定位置的元素,
operator[] 重载函数用于通过索引访问容器中的元素。
#pragma once
#include
//模拟实现
namespace hsl
{
template <class T>
class vector
{
public:
typedef T* iterator;
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
vector()
{}
vector(const vector<T>& v)
{
reserve(v.capacity());
for (auto& e : v)
{
push_back(e);
}
}
template <class InputIterator>
vector(InputIterator first, InputIterator last)
{
while (first != last)
{
push_back(*first);
first++;
}
}
vector(size_t n,const T& val=T())
{
for (size_t i = 0; i < n; i++)
{
push_back(val);
}
}
vector(int n, const T& val = T())
{
for (int i = 0; i < n; i++)
{
push_back(val);
}
}
void swap(vector<T>& v)
{
std::swap(_start, v._start);
std::swap(_finish,v._finish );
std::swap(_endofstorage, v._endofstorage);
}
vector<T>& operator =(vector<T>& v)
{
swap(v);
return *this;
}
~vector()
{
delete[] _start;
_start = _finish = _endofstorage = nullptr;
}
void push_back(const T& x)
{
if (_finish == _endofstorage)
{
size_t cp;
reserve(cp = capacity() == 0 ? 4 : capacity() * 2);
}
*_finish = x;
++_finish;
}
size_t capacity() const
{
return _endofstorage - _start;
}
size_t size() const
{
return _finish - _start;
}
void reserve(size_t n)
{
if (n > capacity())
{
T* tmp = new T[n];
size_t sz = size();
if (_start)
{
// memcpy(tmp, _start, sizeof(T) * n);
for (size_t i = 0; i < size(); i++)
{
tmp[i] = _start[i];
}
delete[] _start;
}
_start = tmp;
_finish = _start+sz;
_endofstorage = _start + n;
}
}
void resize(size_t n,T val = T())
{
if (n <= size())
{
_finish = _start + n;
}
else
{
reserve(n);
/*int begin = size();
while (begin < n)
{
push_back(val);
begin++;
}*/
while (_finish < _start + n)
{
*(_finish) = val;
++_finish;
}
}
}
void insert(iterator pos,const T& x)
{
assert(pos >= _start);
assert(pos <= _finish);
if (_finish == _endofstorage)
{
size_t len = pos - _start;
reserve(capacity() == 0 ? 4 : capacity() * 2);
pos = _start + len;
}
iterator end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
end--;
}
*pos = x;
++_finish;
}
iterator erase(iterator pos)
{
assert(pos >= _start);
assert(pos < _finish);
auto it = pos;
while (it < _finish)
{
*it = *(it + 1);
it++;
}
--_finish;
return pos;
}
T& operator[](size_t pos)
{
assert(pos < size());
return _start[pos];
}
private:
iterator _start=nullptr;
iterator _finish=nullptr;
iterator _endofstorage=nullptr;
};
//测试函数
void test_vector1()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(4);
v1.push_back(4);
v1.push_back(5);
v1.push_back(6);
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
auto it = v1.begin();
while (it != v1.end())
{
if (*it % 2 == 0)
{
it=v1.erase(it);
}
else
{
it++;
}
}
for (auto e : v1)
{
cout << e<<" ";
}
cout << endl;
}
void test_vector2()
{
vector<string> v1;
v1.push_back("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
v1.push_back("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
v1.push_back("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
v1.push_back("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
v1.push_back("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
}
void test_vector3()
{
vector<int> v1(10,1);
vector<int> v2;
v2 = v1;
for (auto e : v2)
{
cout << e << " ";
}
cout << endl;
}
}
#pragma once
#include
namespace hsl
{
template <class T>
class vector
{
public:
typedef T* iterator; // 迭代器类型定义为指向 T 类型的指针
iterator begin() // 返回指向容器起始位置的迭代器
{
return _start;
}
iterator end() // 返回指向容器结束位置的迭代器
{
return _finish;
}
vector() // 默认构造函数
{}
vector(const vector<T>& v) // 拷贝构造函数
{
reserve(v.capacity()); // 根据 v 的容量分配内存
for (auto& e : v) // 遍历 v 中的元素
{
push_back(e); // 将元素添加到当前 vector 中
}
}
template <class InputIterator>
vector(InputIterator first, InputIterator last) // 范围构造函数
{
while (first != last) // 遍历指定范围内的元素
{
push_back(*first); // 将元素添加到当前 vector 中
first++; // 移动迭代器
}
}
// 构造函数:创建一个指定大小的 vector,并用指定的值进行初始化
vector(size_t n, const T& val = T())
{
for (size_t i = 0; i < n; i++)
{
push_back(val); // 将指定值 val 添加到 vector 中
}
}
// 构造函数:创建一个指定大小的 vector,并用指定的值进行初始化
vector(int n, const T& val = T())
{
for (int i = 0; i < n; i++)
{
push_back(val); // 将指定值 val 添加到 vector 中
}
}
// 交换两个 vector 对象的内容
void swap(vector<T>& v)
{
std::swap(_start, v._start); // 交换容器的起始位置
std::swap(_finish, v._finish); // 交换容器的结束位置
std::swap(_endofstorage, v._endofstorage); // 交换容器的内存结束位置
}
// 赋值运算符重载
vector<T>& operator =(vector<T>& v)
{
swap(v); // 交换当前 vector 和 v 的内容
return *this; // 返回当前 vector 对象
}
// 析构函数:释放 vector 对象所占用的内存
~vector()
{
delete[] _start; // 释放内存
_start = _finish = _endofstorage = nullptr; // 将迭代器置空
}
// 在 vector 的末尾添加一个元素
void push_back(const T& x)
{
if (_finish == _endofstorage) // 如果内存空间不足
{
size_t cp;
reserve(cp = capacity() == 0 ? 4 : capacity() * 2); // 扩容
}
*_finish = x; // 将元素 x 添加到末尾
++_finish; // 更新结束位置的迭代器
}
// 返回 vector 的容量大小
size_t capacity() const
{
return _endofstorage - _start; // 返回分配的内存大小
}
// 返回 vector 的元素个数
size_t size() const
{
return _finish - _start; // 返回当前元素个数
}
// 调整 vector 的容量
void reserve(size_t n)
{
if (n > capacity()) // 如果需要的容量大于当前分配的内存大小
{
T* tmp = new T[n]; // 申请新的内存空间
size_t sz = size();
if (_start) // 如果原始 vector 不为空
{
for (size_t i = 0; i < size(); i++)
{
tmp[i] = _start[i];
}
delete[] _start;
}
_start = tmp; // 更新起始位置的迭代器
_finish = _start + sz; // 更新结束位置的迭代器
_endofstorage = _start + n; // 更新内存结束位置的迭代器
}
}
// 调整 vector 的大小,并用指定的值填充新元素
void resize(size_t n, T val = T())
{
if (n <= size()) // 如果指定大小小于等于当前元素个数
{
_finish = _start + n; // 更新结束位置的迭代器
}
else
{
reserve(n); // 调整容器的容量
while (_finish < _start + n) // 如果结束位置的迭代器还未到达指定大小
{
*(_finish) = val; // 添加指定值 val 到结束位置
++_finish; // 更新结束位置的迭代器
}
}
}
// 在指定位置插入一个元素
void insert(iterator pos, const T& x)
{
assert(pos >= _start); // 断言:插入位置在合法范围内
assert(pos <= _finish);
if (_finish == _endofstorage) // 如果内存空间不足
{
size_t len = pos - _start;
reserve(capacity() == 0 ? 4 : capacity() * 2); // 扩容
pos = _start + len; // 更新插入位置的迭代器
}
iterator end = _finish - 1; // 获取原始结束位置的迭代器
while (end >= pos) // 从插入位置开始,将元素后移一位
{
*(end + 1) = *end;
end--;
}
*pos = x; // 在插入位置处添加元素
++_finish; // 更新结束位置的迭代器
}
// 删除指定位置的元素
iterator erase(iterator pos)
{
assert(pos >= _start); // 断言:删除位置在合法范围内
assert(pos < _finish);
iterator begin = pos + 1; // 获取删除位置的下一个位置的迭代器
while (begin != _finish) // 将元素前移一位
{
*(begin - 1) = *begin;
++begin;
}
--_finish; // 更新结束位置的迭代器
return pos; // 返回删除位置的迭代器
}
// 重载 [] 运算符,通过索引访问容器中的元素
T& operator [](size_t index)
{
assert(index >= 0 && index < size()); // 断言:索引在合法范围内
return _start[index]; // 返回对应索引位置的元素引用
}
private:
iterator _start; // 指向容器起始位置的迭代器
iterator _finish; // 指向容器结束位置的迭代器
iterator _endofstorage; // 指向容器分配的内存结束位置的迭代器
};
void test_vector1()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(4);
v1.push_back(4);
v1.push_back(5);
v1.push_back(6);
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
auto it = v1.begin();
while (it != v1.end())
{
if (*it % 2 == 0)
{
it=v1.erase(it);
}
else
{
it++;
}
}
for (auto e : v1)
{
cout << e<<" ";
}
cout << endl;
}
void test_vector2()
{
vector<string> v1;
v1.push_back("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
v1.push_back("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
v1.push_back("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
v1.push_back("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
v1.push_back("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
}
void test_vector3()
{
vector<int> v1(10,1);
vector<int> v2;
v2 = v1;
for (auto e : v2)
{
cout << e << " ";
}
cout << endl;
}
}
(本章完)