vector
动态数组,随机存取 ; O ( 1 ) p u s h b a c k 、 p o p b a c k ; 近似 O ( n ) p o p 中间元素 . 动态数组,随机存取;O(1)pushback、popback;近似O(n)pop中间元素. 动态数组,随机存取;O(1)pushback、popback;近似O(n)pop中间元素.
(1)vector对象的默认构造:
vector<datatype>vecT;
vecT=vecT_2;//=号重载
(2)vector对象的带参数构造:
//eg1:
int aray[]={0,1,2,3,4};
vector<int>e(aray,aray+5);//左闭右开[)
//eg2:
vector<int>e(3,10);//存取3个10
//eg3:
vector<int>v1(v2);//v2是vector<int>对象
(3)assign函数:
vector<int>e1,e2,e3,e4;
e1.assign(beg,end);//将[beg,end)中的数据copy复制给e1
e1.assign(e2.begin(),e2.end());//将e2中的容器内容传给e1
e1.assign(4,10);//将4个10拷贝到e1
(4)swap函数:
e1.swap(e1,e2);//互换e1和e2中的元素,size也会换
(5)大小与空(size,empty,resize):
vector<int>e1;
e1.size();//返回容器中元素的个数
e1.empty();//返回是否为空?0:1
e1.resize(num,elem);//重新指定容器的长度为num,若容器变长,则以默认值elem填充新的位置;如果变短,则删除多余元素.
e1.resize(num);//不写elem,elem默认为0;
(6)访问方式(at,下标,front,back):
//at的好处就是可以告诉你越界
vector<int>e1;
e1.at(idx);//返回索引idx所指的数据,如果idx越界,抛出异常 std::out_of_range
e1[idx];//返回索引idx所指的数据,无法判断越界与否
e1.front();//头
e1.back();//尾
(7)插入与删除(insert(),push_back(),pop_back(),erase,clear):
vector<int>e1;
e1.push_back(x);
e1.pop_back();
e1.insert(pos,elem);//在pos位置插入一个elem元素,返回新数据的的位置.
e1.insert(pos,n,elem);//在pos位置插入n个elem元素,无返回值.
e1.insert(pos,beg,end);//在pos位置上插入[beg,end)区间的数据,无返回值.
e1.erase(e1.begin()+1);//删除第二个元素,返回下一个元素的迭代器.
e1.erase(e1.begin()+1,e1.begin()+3);//删除第2个和第3个元素,返回e1.begin()+3;
e1.erase(2);//删除e1中的第一个2
e1.clear();//清空
(8)vector容器迭代器的使用:
vector<int>e1;
vector<int>::iterator it;//可以不严谨地理解为指针
it=e1.begin();
cout<< (*it) <<endl;
for(it= e1.begin();it!=e1.end();it++) cout<<(*it)<<endl;
(9)vector迭代器失效:
- 插入元素导致迭代器失效
int main()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);//v有三个元素 1,2,3,4
vector<int>::iterator it1 = v.begin() + 3;
v.insert(it1, 8);//插入一个8
cout << *it1 << endl;//输出it位置的元素
return 0;
}
运行上面这段代码,我们会发现输出的结果并不是8,甚至有可能会导致程序崩溃。这是为什么呢?
因为在insert时,vector可能需要进行扩容,而扩容的本质是new一块新的空间,再将数据迁移过去。而我们知道,迭代器的内部是通过指针访问容器中的元素的,而插入后,若vector扩容,则原有的数据被释放,指向原有数据的迭代器就成了野指针,所以迭代器失效了。
而解决的办法很简单,insert函数提供了返回值,这个返回值是指向插入之后的val的迭代器。我们只需要保存返回的迭代器,并使用这个新的迭代器即可。
- 删除元素导致迭代器失效
vector<int> cont ={1,2,3,3,3,4,5,5,5,6};
for (iter = cont.begin(); iter != cont.end();iter++)
{
if (*iter == 3)
cont.erase(iter);
}
对于序列式容器(如vector,deque),序列式容器就是数组式容器,删除当前的iterator会使后面所有元素的iterator都失效。这是因为vetor,deque使用了连续分配的内存,删除一个元素导致后面所有的元素会向前移动一个位置。所以不能使用erase(iter++)的方式,还好erase方法可以返回下一个有效的iterator。
解决办法:
vector<int> cont ={1,2,3,3,3,4,5,5,5,6};
for (iter = cont.begin(); iter != cont.end();)
{
if (*iter == 3)
iter = cont.erase(iter);
else
iter++;
}