容器之vector

vector容器类:

#include <vector>
std::vector<int> MyVector;

作为vector的元素,要求元素能够进行赋值和拷贝操作,即元素类型拥有赋值运算符和拷贝构造函数,
如果元素类型是用户自定义类型,operator=和拷贝构造函数可以是用户定义的,也可以是编译器自动
生成的。(注意编译器产生的有可能引发错误,例如类型的成员包含指针就有可能引起错误)。


vector的特征:

1.支持自由存取。
2.使用自由存取迭代器,因此可以使用STL的所有算法。(注:STL的有些算法只支持自由存取迭代器,
  因此如果容器不支持自由存取,即容器使用的不是自由存取迭代器,则这些容器不能使用这些算法)
3.在末端追加和删除元素效率高。


大小和容量(size和capacity):

除了通用的size(),empty()和max_size()函数外,vector还拥有capacity()函数。

capacity()返回一个vector的实际内存中能够容纳的字符数(容量),如果超过了这个数目,这个vector
必须重新分配它的内存空间,将获取一块更大的空间。例如:如果你在container后面用push_back(),
安插元素,当安插的元素多于capacity()-size()时,这个vector的内存将会被重新分配。

重新分配将会增加vector的capacity(),size()和max_size不会改变,但会使指向此vector的任何迭代器
失效,因此应该避免重新分配。

max_size: 是这个container可能容纳的最大数目,是常量。  
size:container现在存放的元素数量,相关函数:resize()  
capacity:如果在size==capacity的情况下增加容器的元素,capacity就会变大,相关函数:reserve()  
如果删除一个元素,size会变小,但是capacity不变。

避免重新分配的方法:

方法一:使用reserve函数。

std::vector<int> v; // create an empty vector
v.reserve (80); // reserve memory for 80 elements

方法二:

std::vector<T> v(5); // creates a vector and initializes it with five values
                     // (calls five times the default constructor of type T)

因为效率原因,我们应该使用方法一。


创建、拷贝、销毁操作:

vector<Elem> c
vector<Elem> c1(c2)
vector<Elem> c(n)
c.~vector<Elem>()

vector<Elem> c(n,elem)
vector<Elem> c(beg,end)

非修改操作(包括大小操作和比较操作):

c.size()
c.empty()
c.max_size()
capacity()
reserve()
c1 == c2
c1 != c2
c1 < c2
c1 > c2
c1 <= c2
c1 >= c2

reserve(n)  增加容量至n,提供的n不小于当前大小。


赋值操作:

c1 = c2
c.assign(n,value)   把n个值为value的元素赋给c
c.assign(beg,end)   把范围[beg,end)内的元素赋给c
c1.swap(c2)
swap(c1,c2)

元素访问操作:

c.at(idx)   返回索引号为idx的元素(如果索引号idx超出范围,抛出range error exception)。
c[idx]      返回索引号为idx的元素(无范围检查)。
c.front()   返回第一个元素(不会检查第一个元素是否存在)。
c.back()    返回最后一个元素(不会检查最后一个元素是否存在)。

因为c[idx]、c.front()和c.back()都没有进行相关的检查,一个范围错误将导致不确定行为。例如:

std::vector<Elem> coll; // empty!
coll [5] = elem; // RUNTIME ERROR ? undefined behavior
std::cout << coll. front (); // RUNTIME ERROR ? undefined behavior

对一个空容器调用[],front()和back()经常导致不确定行为,所以我们在调用[]时必须确保索引号是
有效的,在调用front()和back()时容器是非空的。

std::vector<Elem> coll; // empty!
if (coll.size() > 5) {
coll [5] = elem; // OK
}
if (!coll.empty()) {
cout << coll.front(); // OK
}
coll.at(5) = elem; // throws out_of_range exception

迭代器操作:

c.begin()
c.end()
c.rbegin()
c.rend()

迭代器一直保持有效,直到一个索引号更小的元素插入或移除或发生了重新分配导致容量(capacity)改变。

插入和移除元素操作:

对于使用STL插入和移除元素,必须确保参数是有效的,迭代器必须指向有效的位置,范围的开始位置不在
结束位置的后面,防止从空容器中移除元素。

插入和移除元素将使指向该位置(插入和移除的位置)以后的引用、指针和迭代器失效,如果一个插入操作
引起重新分配,它将使所有的引用、指针和迭代器无效。


c.insert(pos,elem)     在pos迭代器所指的位置处插入一个elem的拷贝,并返回新元素的位置。
c.insert(pos,n,elem)   在pos迭代器所指的位置处插入n个elem的拷贝,没有返回。
c.insert(pos,beg,end)  在pos迭代器所指的位置处插入范围[beg,end)内所有元素的拷贝,没有返回。
c.push_back(elem)      在末尾追加一个elem的拷贝。
c.pop_back()           移除最后一个元素,不会返回这个元素。
c.erase(pos)           移除pos迭代器位置处的元素,并返回下一个元素的位置。
c.erase(beg,end)       移除[beg,end)范围内所有的元素,并返回下一个元素的位置。
c.resize(num)          改变元素的数目为num,如果size()增加,新元素通过默认构造函数创建。
c.resize(num,elem)     改变元素的数目为num,如果size()增加,新元素拷贝elem得到。
c.clear()              移除所有元素(使容器变为空)。


将vector用作普通数组:

对于vector容器类有下面的表达式成立:
&v[i] == &v[0] + i
其中v为vector容器类,定义如下:
std::vector<T> v;

下面看一个vector用作普通数组的例子:

std::vector<char> v;
v.resize(41); // 分配能容纳41个字符的空间,包括'/0'在内。
strcpy(&v[0], "hello, world"); // copy a C-string into the vector
printf("%s/n", &v[0]);

注意:不能将一个迭代器当作第一个元素的地址,迭代器是特别实现、有特殊含义的类型。
例如下面这样写是不对的:

printf("%s/n", v.begin()); // ERROR (might work, but not portable)
printf("%s/n", &v[0]); // OK


最后看一个总结的例子:


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
//create empty vector for strings
vector<string> sentence;
//reserve memory for five elements to avoid reallocation
sentence.reserve(5);
//append some elements
sentence.push_back("Hello,");
sentence.push_back("how");
sentence.push_back("are");
sentence.push_back("you");
sentence.push_back("?");
//print elements separated with spaces
copy (sentence.begin(), sentence.end(),
ostream_iterator<string>(cout," "));
cout << endl;
//print ''technical data''
cout << " max_size(): " << sentence.max_size() << endl;
cout << " size(): " << sentence.size() << endl;
cout << " capacity(): " << sentence.capacity() << endl;
//swap second and fourth element
swap (sentence[1], sentence [3]);
//insert element "always" before element "?"
sentence.insert (find(sentence.begin(),sentence.end(),"?"),
"always");
//assign "!" to the last element
sentence.back() = "!";
//print elements separated with spaces
copy (sentence.begin(), sentence.end(),
ostream_iterator<string>(cout," "));
cout << endl;
//print "technical data" again
cout << " max_size(): " << sentence.max_size() << endl;
cout << " size(): " << sentence.size() << endl;
cout << " capacity(): " << sentence.capacity() << endl;
}
The output of the program might look like this:
Hello, how are you ?
max_size(): 268435455
size(): 5
capacity(): 5
Hello, you are how always !
max_size(): 268435455
size(): 6
capacity(): 10 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值