Vector
三种遍历
迭代器
普通正向迭代
iterator
只读
const_iterator
反向迭代
reverse_iterator rit.rbegin(), rit.rend();
resize(n,char ch) 修改size大小为n,且空数据填充为ch
reserve() 修改capacity空间大小,就不用扩容了
vector<int>::iteator pos = find(v.begin(),v.end(),5);
sort()
迭代器失效
#include <iostream>
using namespace std;
#include <vector>
int main()
{
vector<int> v{1,2,3,4,5,6};
auto it = v.begin();
// 将有效元素个数增加到100个,多出的位置使用8填充,操作期间底层会扩容
// v.resize(100, 8);
// reserve的作用就是改变扩容大小但不改变有效元素个数,操作期间可能会引起底层容量改变
// v.reserve(100);
// 插入元素期间,可能会引起扩容,而导致原空间被释放
// v.insert(v.begin(), 0);
// v.push_back(8);
// 给vector重新赋值,可能会引起底层容量改变
v.assign(100, 8);
/*
出错原因:以上操作,都有可能会导致vector扩容,也就是说vector底层原理旧空间被释放掉,
而在打印时,it还使用的是释放之间的旧空间,在对it迭代器操作时,实际操作的是一块已经被释放的
空间,而引起代码运行时崩溃。
解决方式:在以上操作完成之后,如果想要继续通过迭代器操作vector中的元素,只需给it重新
赋值即可。
*/
while(it != v.end())
{
cout<< *it << " " ;
++it;
}
cout<<endl;
return 0;
}
对于vector insert()和erase()会导致迭代器位置不对,所以失效,带增容的接口都有可能导致迭代器失效
#include <iostream>
using namespace std;
#include <vector>
int main()
{
int a[] = { 1, 2, 3, 4 };
vector<int> v(a, a + sizeof(a) / sizeof(int));
// 使用find查找3所在位置的iterator
vector<int>::iterator pos = find(v.begin(), v.end(), 3);
// 删除pos位置的数据,导致pos迭代器失效。
v.erase(pos);
cout << *pos << endl; // 此处会导致非法访问
return 0;
}
删除容器中所有偶数,erase(it)也会导致之后,也会出现it失效
int main()
{
vector<int> v{ 1, 2, 3, 4 };
auto it = v.begin();
while (it != v.end())
{
if (*it % 2 == 0)
v.erase(it);
++it;
}
return 0;
}
解决办法
it = v.erase(it); //erase()会返回它的下一个位置的迭代器
int main()
{
vector<int> v{ 1, 2, 3, 4 };
auto it = v.begin();
while (it != v.end())
{
if (*it % 2 == 0)
it = v.erase(it);
else
++it;
}
return 0;
}
vector实现
namespace liyf {
template<class T>
class vector
{
public:
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;
}
size_t size()const {
return _finish - _start;
}
size_t capacity()const {
return _endOfStorage - _start;
}
bool empty()const {
return _finish == _start;
}
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);
}
}
vector(const vector<T>& v)
:_start(nullptr),
_finish(nullptr),
_endOfStorage(nullptr)
{
reverse(v.capacity());
iterator it = begin();
const_iterator cit = v.cbegin();
while (cit != v.cend()) {
*it = *cit;
it++;
cit++;
}
}
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;
}
private:
iterator _start;
iterator _finish;
iterator _endOfStorage;//指向存储容量的尾
};
}
reserve(n)
resize()
memcpy(tmp,_strat,sizeof(T)*size());
深浅拷贝问题
vector < string > v;
memcpy(tmp,_start,sizeof(T)*sz); //自定义类型,浅拷贝
练习
只出现一次的数字 https://leetcode.cn/problems/single-number/description/
vector没有 ‘\0’,string才有 ‘\0’,这是他们的区别
memxxx 是按字节给你处理
00000000 00000000 00000000 00000000
00000001 00000001 00000001 00000001