vector:翻译过来是向量,矢量。但是学习过来,给我的感觉类似于顺序表,或者说是数组??
class T代表的是一个类型,是成员变量。
allocator代表的是空间配置器。
在使用STL的三个境界:能用,明理,能扩展。
在介绍vector的时候,需要结合文档来学习:链接: vector
vector v1;
vector v2(10, 1); vector v3(5, 'x'); vector v4(6, "hello");
int a[4] = { 4,27,22,20 }; vector v5(a, a + 4);
这种方式可以使用自己的迭代器进行构造:
vector v1(10, 1); vector v2(v1.begin(), v1.end());
同时也可以使用其他容器的迭代器:
string str("hello world"); vector v(str.begin(), str.end());
【说明】STL中包括容器(存储数据)和算法(对数据进行处理),在算法中有一个sort()函数,头文件为< algorithm >,就是使用迭代器进行排序的。
下面进行升序排序操作:
int a[4] = { 4,27,22,20 }; vector v(a, a + 4); sort(v.begin(), v.end()); for (size_t i = 0; i < v.size(); ++i) { cout << v[i] << " "; } cout << endl;
下面进行降序排序操作:
int a[4] = { 4,27,22,20 }; vector v(a, a + 4); greater g; sort(v.begin(), v.end(), g); for (size_t i = 0; i < v.size(); ++i) { cout << v[i] << " "; } cout << endl;
降序操作也可以写成匿名对象的方式:
int a[4] = { 4,27,22,20 }; vector v(a, a + 4); sort(v.begin(), v.end(), greater()); for (size_t i = 0; i < v.size(); ++i) { cout << v[i] << " "; } cout << endl;
其他容器也是允许被排序的,例如string类,数组等等。
vector v6(10, 2); vector v7(v6);
【注意】了解vector的基本原理之后,可以觉得vector已经可以代替string了,但是这是不可取的。
vector< char > 不能代替string的原因:
首先俩者是存在不同点的,string后面保证会出现’\0’,这是为了像C兼容,而vector是不会自动出现"\0"的,需要手动添加,而手动添加的代价就是难免会忘记。同时,string的接口是要比vector更加丰富的,很多关于string的专业接口函数。例如:vector的比较大小相较于string类的比较大小是没有意义的。
vector是针对所有类型的,同时vector也是可以引用string类的。
vector v;
可以向string类型的vector添加字符串:
string name1("大柏"); v.push_back(name1);
这里可以替换成匿名对象
v.push_back(string("大柏"));
也可以直接添加字符串:
v.push_back("大柏");
需要注意的是,这里直接添加字符串是相当于隐式类型转换,将字符串先进行拷贝构造,然后再进行构造,系统会直接优化成直接构造。
vector v1(10, 5); vector v2; v2 = v1;
【注意】迭代器无const可以进行读写,而有const只能进行度。
vector v(10, 5); vector::iterator it = v.begin(); while (it != v.end()) { cout << *it << " "; ++it; } cout << endl;
使用反向迭代器也可以进行排降序:
int a[4] = { 4,27,22,20 }; vector v(a, a + 4); sort(v.rbegin(), v.rend()); for (size_t i = 0; i < v.size(); ++i) { cout << v[i] << " "; } cout << endl;
vector v(10, 5); cout << v.size() << endl;
【注意】不同的平台,最大的存储值不同
vector v(10, 5); cout << v.max_size() << endl;
vector v(10, 5); v.resize(20, 1); for (size_t i = 0; i < v.size(); ++i) { cout << v[i] << " "; } cout << endl;
下面是一段测试默认扩容机制
// 测试vector的默认扩容机制 void TestVectorExpand() { size_t sz; vector v; sz = v.capacity(); cout << "making v grow:\n"; for (int i = 0; i < 100; ++i) { v.push_back(i); if (sz != v.capacity()) { sz = v.capacity(); cout << "capacity changed: " << sz << '\n'; } } }
使用这段代码分别在vs环境下和gcc环境下测试会发现,vs下capacity是以1.5倍增长的,而gcc环境下capacity是以2倍增长的。具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。
vector v1(10, 5); vector v2; cout << v1.empty() << endl; cout << v2.empty() << endl;
vector v(10, 5); v.reserve(30); cout << v.capacity() << endl;
【注意】
1.使用reserve时是不允许使用下标[ ]的,这是因为下标[ ]在使用时需要调用size,而reserve不会改变size。
2.使用reserve需要添加数据时,可以使用push_back;使用resize添加数据时,可以使用下标+[ ]。这是因为reserve只能开辟空间,并不能改变size大小;而resize不仅可以开辟空间,同时也会改变size
vector v(10, 5); for (size_t i = 0; i < v.size(); ++i) { v[i] = i; }
vector v(10, 5); for (size_t i = 0; i < v.size(); ++i) { v.at(i) = i; }
【注意】使用下标+[ ]与at基本没有差别,唯一的差距是,使用下表+[] 报错时会断言,而使用at报错时会抛异常。
int a[4] = { 4,27,22,20 }; vector v(a, a + 4); cout << v.front() << endl;
int a[4] = { 4,27,22,20 }; vector v(a, a + 4); cout << v.back() << endl;
vector v(10, 5); v.assign(20, 1); for (size_t i = 0; i < v.size(); ++i) { cout << v[i] << " "; } cout << endl;
vector v(10, 5); v.push_back(1); for (size_t i = 0; i < v.size(); ++i) { cout << v[i] << " "; } cout << endl;
int a[4] = { 4,27,22,20 }; vector v(a, a + 4); v.pop_back(); for (size_t i = 0; i < v.size(); ++i) { cout << v[i] << " "; } cout << endl;
int a[4] = { 4,27,22,20 }; vector v(a, a + 4); v.insert(v.begin() + 2, 15); for (size_t i = 0; i < v.size(); ++i) { cout << v[i] << " "; } cout << endl;
int a[4] = { 4,27,22,20 }; vector v(a, a + 4); v.erase(v.begin() + 1); for (size_t i = 0; i < v.size(); ++i) { cout << v[i] << " "; } cout << endl;
int a[4] = { 4,27,22,20 }; vector v1(a, a + 4); vector v2(10, 5); v1.swap(v2);
vector v2(10, 5); v2.clear();