“vector字典”
约等于顺序表
reserve
小于size,不会缩容
resize
会缩容,空间不够会用给的缺省值初始化新构造的数字
insert(支持迭代器)
不支持流插入,流提取
隐式类型转换
std::string
可以接受const char*
类型的参数,从而实现这种隐式类型转换
二维数组实现
118. 杨辉三角
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> vv(numRows);
for(int i=0;i<numRows;i++)
{
vv[i].resize(i+1,1);
}
for(int i=2;i<numRows;i++)
{
for(int j=1;j<i;j++)
{
vv[i][j]=vv[i-1][j-1]+vv[i-1][j];
}
}
return vv;
}
};
代码实现
迭代器失效:
1.会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resize、reserve、insert、
assign、push_back等
insert,空间不够需要扩容,reserve,需要记录原先的size(),扩容后,原先的空间被释放
2. 指定位置元素的删除操作--erase
如果pos刚好是最后一个元素,删完之后pos刚好是end的位置,而end位置是没有元素的,那么pos就失效了。因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效了
库里erase需要更新it的位置,因为删除的同时it在移动,end()也在减小,不更新it,会造成死循环
3. 注意:Linux下,g++编译器对迭代器失效的检测并不是非常严格,处理也没有vs下极端。
4. 与vector类似,string在插入+扩容操作+erase之后,迭代器也会失效
迭代器失效解决办法:在使用前,对迭代器重新赋值即可
memcpy拷贝问题
1. memcpy是内存的二进制格式拷贝,将一段内存空间中内容原封不动的拷贝到另外一段内存
空间中
2. 如果拷贝的是自定义类型的元素,memcpy既高效又不会出错,但如果拷贝的是自定义类型
元素,并且自定义类型元素中涉及到资源管理时,就会出错,因为memcpy的拷贝实际是浅拷贝
vector.h
#pragma once
#include"iostream"
#include"assert.h"
#include<algorithm>
using namespace std;
namespace bit
{
template<class T>
class vector
{
public:
typedef T* iterator;
typedef const T* const_iterator;
size_t size() const
{
return _finish - _start;
}
size_t capacity() const
{
return _end_of_storage - _start;
}
bool empty(const vector<int>& v)
{
return _start == _finish;
}
void pop_back(const vector<int>& v)
{
assert(!empty(v));
--_finish;
}
void print_vector(const vector<int>& v)
{
vector<int>::const_iterator it = v.begin();
while (it != v.end())
{
cout << *it << " ";
it++;
}
cout << endl;
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
}
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
const_iterator begin()const
{
return _start;
}
const_iterator end() const
{
return _finish;
}
void reserve(size_t n)
{
if (n > capacity())
{
size_t old_size = size();
T* tmp = new T[n];
//浅拷贝
//memcpy(tmp, _start, size() * sizeof(T));
//调用string深拷贝
for (int i = 0; i < old_size; i++)
{
tmp[i] = _start[i];
}
delete[]_start;
_start = tmp;
_finish = tmp + old_size;
_end_of_storage = tmp + n;
}
}
void push_back(const T& x)
{
if (_finish == _end_of_storage)
{
reserve(capacity() == 0 ? 4 : capacity() * 2);
}
*_finish = x;
++_finish;
}
//迭代器失效
iterator insert(iterator pos, const T& x)
{
assert(pos >= _start);
assert(pos <= _finish);
if (_finish == _end_of_storage)
{
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;
return pos;
}
void erase(iterator pos)
{
assert(pos >= _start);
assert(pos < _finish);
iterator it = pos + 1;
while (it != end())
{
*(it - 1) = *it;
++it;
}
--_finish;
}
void resize(size_t n, T val = T())
{
if (n < size())
{
_finish = _start + n;
}
else
{
reserve(n);
while (_finish < _start + n)
{
*_finish = val;
++_finish;
}
}
}
T& operator[](size_t i)
{
assert(i < size());
return _start[i];
}
const T& operator[](size_t i) const
{
assert(i < size());
return _start[i];
}
//类模板的成员函数,还可以继续是函数模板
template <class InputIterator>
vector(InputIterator first, InputIterator last)
{
while (first != last)
{
push_back(*first);
++first;
}
}
/*vector(size_t n, const T& val = T())
{
reserve(n);
for (size_t i = 0; i < n; i++)
{
push_back(val);
}
}*/
vector(int n, const T& val = T())
{
reserve(n);
for (int i = 0; i < n; i++)
{
push_back(val);
}
}
void clear()
{
_finish = _start;
}
//赋值拷贝
vector<int>& operator=(const vector<int>& v)
{
if (this != &v)
{
clear();
reserve(v.size());
for (auto& e : v)
{
push_back(e);
}
}
return *this;
}
void swap(vector<int>& v)
{
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_end_of_storage, v._end_of_storage);
}
//类里可以用类名替代类型
vector& operator=(vector<T> v)
//vector<T>& operator=(vector<T> v)
{
swap(v);
return *this;
}
//构造函数
/*vector()
{}*/
//强制生成默认构造 c++11
vector() = default;
//拷贝构造
vector(const vector<int>& v)
{
reserve(v.size());
for (auto& e : v)
{
push_back(e);
}
}
~vector()
{
if (_start)
{
delete[]_start;
_start = _finish = _end_of_storage = nullptr;
}
}
private:
iterator _start = nullptr;
iterator _finish = nullptr;
iterator _end_of_storage = nullptr;
};
/*void print_vector(const vector<int>& v)
{
vector<int>::const_iterator it = v.begin();
while (it != v.end())
{
cout << *it << " ";
it++;
}
cout << endl;
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
}*/
template<class T>
void print_vector(const vector<T>& v)
{
//规定,没有实例化的类模板里面取东西,编译器不能区分这里const_iterator
//是类型还是静态成员变量
typename vector<T>::const_iterator it = v.begin();
while (it != v.end())
{
cout << *it << " ";
it++;
}
cout << endl;
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
}
template<class Container>
void print_container(const Container& v)
{
//规定,没有实例化的类模板里面取东西,编译器不能区分这里const_iterator
//是类型还是静态成员变量
//typename Container::const_iterator it = v.begin();
auto it = v.begin();
while (it != v.end())
{
cout << *it << " ";
it++;
}
cout << endl;
/*for (auto e : v)
{
cout << e << " ";
}
cout << endl;*/
}
void test_vector()
{
/*std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5); */
//for (size_t i = 0; i < v.size(); i++)
//{
// cout << v[i] << " ";
//}
//cout << endl;
insert不能引用,临时变量具有常性,会造成权限放大
//v.insert(v.begin() + 2, 30);
//print_container(v);
v.print_vector(v);
print_vector(v);
//
//int x = 0;
//cin >> x;
//auto pos = find(v.begin(), v.end(), x);
//if (pos != v.end())
//{
// //insert后迭代器pos失效,不要访问
// //v1.insert(pos, 30.1);
// //insert以后p就是失效,不要直接访问,要访问就要更新这个失效的迭代器的值
// pos = v.insert(pos, 40);
// (*(pos + 1)) *= 10;
// 报错,位置未更新
// //v.insert(pos, 2);
// //(*pos) *= 10;
//
//}
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(4);
v.push_back(4);
v.push_back(5);
v.push_back(5);
v.push_back(5);
v.push_back(4);
auto it = v.begin();
while (it != v.end())
{
if (*it % 2 == 0)
{
v.erase(it);
}
else
{
it++;
}
}
print_container(v);
//vector<double> v1;
//v1.push_back(1.1);
//v1.push_back(2.1);
//v1.push_back(3.1);
//v1.push_back(4.1);
//print_vector(v1);
//
//int x = 0;
//cin >> x;
//auto pos = find(v.begin(), v.end(),x);
//if (pos != v.end())
//{
// //insert后迭代器pos失效,不要访问
// //v1.insert(pos, 30.1);
// pos = v.insert(pos, 40.1);
// (*(pos + 1)) *= 10;
//}
//print_vector(v1);
}
void test_vector1()
{
vector<int> v;//默认构造函数
/*v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);*/
v.resize(10,1);
print_vector(v);
v.resize(15, 200);
print_vector(v);
v.reserve(5);
print_vector(v);
v.resize(5);
print_vector(v);
}
//void test_vector2()
//{
// vector<int> v;
// v.push_back(1);
// v.push_back(2);
// v.push_back(3);
// v.push_back(4);
// vector<int> v1(v);
// print_vector(v1);
// vector<int> v3 = v1;
// print_vector(v3);
//}
void test_vector3()
{
/*vector<int> v2(10u, 1);
print_container(v2);*/
vector<int> v1(10,1);
print_container(v1);
}
void test_vector4()
{
//扩容造成的失败
vector<string> v1;
v1.push_back("1111111111111111111");
v1.push_back("1111111111111111111");
v1.push_back("1111111111111111111");
v1.push_back("1111111111111111111");
print_container(v1);
v1.push_back("1111111111111111111");
v1.push_back("1111111111111111111");
v1.push_back("1111111111111111111");
v1.push_back("1111111111111111111");
print_container(v1);
}
}
test.cpp
#include"iostream"
#include"vector"
using namespace std;
void test_i()
{
//构造函数
vector<int> v1;
vector<int> v2(10, 1);
vector<int> v3(++v2.begin(), --v2.end());
//便历下标
for (size_t i = 0; i < v3.size(); i++)
{
cout << v3[i] << " ";
}
cout << endl;
vector<int>::iterator it = v3.begin();
while (it != v3.end())
{
cout << *it << " ";
it++;
}
cout << endl;
for (auto e : v3)
{
cout << e << " ";
}
}
void test_vector()
{
// 测试vector的默认扩容机制
size_t sz;
vector<int> v;
sz = v.capacity();
cout << "making v grow:" << sz << endl;
for (int i = 0; i < 100; ++i)
{
v.push_back(i);
if (sz != v.capacity())
{
sz = v.capacity();
cout << "capacity changed: " << sz << '\n';
}
}
}
void test_string32()
{
char str8[] = "牛马";//默认
cout << sizeof(str8) << endl;//两个汉字加'\0'
cout << str8 << endl;
char16_t str16[] = u"牛马";//2个字节为单位
cout << sizeof(str16) << endl;//任何一个符号最少占两个字节
cout << str16 << endl;
char32_t str32[] = U"牛马";//4个字节为单位
cout << sizeof(str32) << endl;
cout << str32 << endl;
wchar_t wstr[] = L"牛马";
cout << sizeof(wstr) << endl;
cout << wstr << endl;
}
void test_vector1()
{
vector<int> v1(10, 1);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
v1.reserve(10);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
v1.reserve(5);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
v1.reserve(20);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
}
void test_vector2()
{
vector<int> v1(10, 1);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
v1.resize(10);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
v1.resize(5);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
v1.resize(20);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
}
void test_vector3()
{
/*vector<int> v1(10, 1);
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
v1.push_back(20);
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
v1.insert(v1.begin(), 100);
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;*/
vector<int> v1(5, 1);
for (size_t i = 0; i < 5; i++)
{
cin >> v1[i];
}
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
}
void test_vector4()
{
// vector<string> v1;
// v1.push_back("yyyyyy");//const char* 隐式类型转换为string
// //for (auto e : v1)//传值传参会调用拷贝构造,string类,消耗大
// //{
// // cout << e << " ";
// //
// //}
// //cout << endl;
//
// for (const auto& e : v1)
// {
// cout << e << " ";
//
// }
// cout << endl;
//二维数组
//10*5
vector<int> v(5, 1);
vector<vector<int>> vv(10,v);
vv[2][1] = 100;
}
//int main()
//{
// //test_string32();
// //test_i();
//
// //reserve
// //test_vector();
// //test_vector1();
// //test_vector2();
// //test_vector3();
// test_vector4();
//}
#include"vector.h"
int main()
{
bit::test_vector();
//bit::test_vector1();
//bit::test_vector2();
//bit::test_vector3();
//bit::test_vector4();
}
namespace bit
{
template<class T>
class vector
{
public:
// Vector的迭代器是一个原生指针
typedef T* iterator;
typedef const T* const_iterator;
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
const_iterator cbegin()const
{
return _start;
}
const_iterator cend() const
{
return _finish;
}
// construct and destroy
vector(): _start(nullptr), _finish(nullptr), _endOfStorage(nullptr)
{}
vector(int n, const T& value = T())
: _start(nullptr), _finish(nullptr),_endOfStorage(nullptr)
{
reserve(n);
while (n--)
{
push_back(value);
}
}
template<class InputIterator>
vector(InputIterator first, InputIterator last)
{
reserve(last - first);
while (first != last)
{
push_back(*first);
++first;
}
}
vector(const vector<T>& v)
: _start(nullptr), _finish(nullptr), _endOfStorage(nullptr)
{
reserve(v.capacity());
iterator it = begin();
const_iterator vit = v.cbegin();
while (vit != v.cend())
{
*it++ = *vit++;
}
_finish = _start + v.size();
_endOfStorage = _start + v.capacity();
}
vector<T>& operator= (vector<T> v)
{
swap(v);
return *this;
}
~vector()
{
delete[] _start;
_start = _finish = _endOfStorage = nullptr;
}
// capacity
size_t size() const
{
return _finish - _start;
}
size_t capacity() const
{
return _endOfStorage - _start;
}
void reserve(size_t n)
{
if (n > capacity())
{
size_t oldSize = size();
T* tmp = new T[n];
if (_start)
{
for (size_t i = 0; i < oldSize; ++i)
tmp[i] = _start[i];
}
_start = tmp;
_finish = _start + size;
_endOfStorage = _start + n;
}
}
void resize(size_t n, const T& value = T())
{
// 1.如果n小于当前的size,则数据个数缩小到n
if (n <= size())
{
_finish = _start + n;
return;
}
// 2.空间不够则增容
if (n > capacity())
reserve(n);
// 3.将size扩大到n
iterator it = _finish;
iterator _finish = _start + n;
while (it != _finish)
{
*it = value;
++it;
}
}
///access///
T& operator[](size_t pos)
{
return _start[pos];
}
const T& operator[](size_t pos)const
{
return _start[pos];
}
///modify/
void push_back(const T& x)
{
insert(end(), x);
}
void pop_back()
{
erase(--end());
}
void swap(vector<T>& v)
{
swap(_start, v._start);
swap(_finish, v._finish);
swap(_endOfStorage, v._endOfStorage);
}
iterator insert(iterator pos, const T& x)
{
assert(pos <= _finish);
// 空间不够先进行增容
if (_finish == _endOfStorage)
{
size_t size = size();
size_t newCapacity = (0 == capacity())? 1 : capacity() * 2;
reserve(newCapacity);
// 如果发生了增容,需要重置pos
pos = _start + size;
}
iterator end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
--end;
}
*pos = x;
++_finish;
return pos;
}
// 返回删除数据的下一个数据
// 方便解决:一边遍历一边删除的迭代器失效问题
iterator erase(Iterator pos)
{
// 挪动数据进行删除
iterator begin = pos + 1;
while (begin != _finish)
{
*(begin - 1) = *begin;
++begin;
}
--_finish;
return pos;
}
private:
iterator _start; // 指向数据块的开始
iterator _finish; // 指向有效数据的尾
iterator _endOfStorage; // 指向存储容量的尾
};
}