vector
标准库类型vector表示对象的集合,能容纳绝大多数类型的对象。
#include <vector>
using std::vector;
动态扩展:
- 并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间
1 定义和初始化
vector<T> v1; //
vector<T> v2(v1); //
vector<T> v2 = v1; //
vector<T> v3(n, val); //
vector<T> v4(n); //
vector<T> v5{a,b,c... };//
vector<T> v5={a,b,c...};//
构造函数
函数原型:
vector<T> v;
//采用模板实现类实现,默认构造函数vector(v.begin(), v.end());
//将v[begin(), end())区间中的元素拷贝给本身。vector(n, elem);
//构造函数将n个elem拷贝给本身。vector(const vector &vec);
//拷贝构造函数。
数组构造vector:
void test02()
{
int ia[] = {0,1,2,3,4,5,6,7,8,9};
int *beg = begin(ia);
int *last = end(ia);
vector<int> v1 (*beg,*last);//这个不行!!
vector<int> v2 (ia,ia+sizeof(ia)/sizeof(int));
for (auto num:v1)
{
cout<<num<<" ";
}
cout<<endl;
for (auto num:v2)
{
cout<<num<<" ";
}
cout<<endl;
}
()与{}
用圆括号表示用括号内提供的值来构造vector对象
用花括号表示用括号内提供的值来列表初始化vector对象,初始化尽可能把花括号的值当成是元素初始值
vector<int> v1(10); //v1中有10个元素,每个值为0
vector<int> v2{10}; //v1中有1个元素,值为10
vector<int> v3(10,1); //v1中有10个元素,每个值为1
vector<int> v2{10,1}; //v1中有2个元素,值为10,1
当列表初始化无法执行时,会考虑其他初始化方式
vector<string> v5{"hi"}; //列表初始化:v5中一个元素
vector<string> v6("hi"); //错误,不能用字面值构建vector对象
vector<string> v7{10}; //v7中10个默认初始化的元素
vector<string> v8{10, "hi"}; //v8中10个值为"hi"的元素
2 vector操作
v.empty() //是否为空
v.size() //返回元素个数
v.push_back(t) //尾部添加元素t
v[n] //返回v中第n个位置元素的 **引用**
v1 = v2 //将v2的元素拷贝 替换v1的元素
v1 = {a,b,c...} //用列表中的拷贝 替换v1中的元素
v1 == v2 //元素数量相同且对应位置值相同时 为true
v1 != v2 //
<, <=, >, >= //字典顺序(元素可比较时,才能比较vector对象的大小)
vector不能用下标的方式添加新元素
2.1 迭代器遍历元素
#include<iostream>
#include<string>
#include<vector>
#include <algorithm> //for_each
using namespace std;
void MyPrint(int num)
{
cout<<num<<endl;
}
void test01()
{
//创建vector容器对象,并且通过模板参数指定容器中存放的数据的类型
vector<int> v;
//向容器中放数据
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
//每一个容器都有自己的迭代器,迭代器是用来遍历容器中的元素
//v.begin()返回迭代器,这个迭代器指向容器中第一个数据
//v.end()返回迭代器,这个迭代器指向容器元素的最后一个元素的下一个位置
//vector<int>::iterator 拿到vector<int>这种容器的迭代器类型
vector<int>::iterator pBegin = v.begin();
vector<int>::iterator pEnd = v.end();
//第一种遍历方式:
while (pBegin != pEnd) {
cout << *pBegin << endl;
pBegin++;
}
cout << "---------------------"<<endl;
//第二种遍历方式:
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << endl;
}
cout << "---------------------"<<endl;
//第三种遍历方式:
//使用STL提供标准遍历算法
for_each(v.begin(), v.end(), MyPrint);
cout << "---------------------"<<endl;
//匿名函数
for_each(v.begin(), v.end(), [=](int num){cout<<num<<endl;});
}
int main()
{
test01();
return 0;
}
打印结果:
10
20
30
40
---------------------
10
20
30
40
---------------------
10
20
30
40
---------------------
10
20
30
40
2.2 赋值操作
函数原型:
-
vector& operator=(const vector &vec);
//重载等号操作符 -
assign(beg, end);
//将[beg, end)区间中的数据拷贝赋值给本身。 -
assign(n, elem);
//将n个elem拷贝赋值给本身。
2.3 容量和元素个数
函数原型:
-
empty();
//判断容器是否为空 -
capacity();
//容器的容量 -
size();
//返回容器中元素的个数 -
resize(int num);
//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。 //如果容器变短,则末尾超出容器长度的元素被删除。
-
resize(int num, elem);
//重新指定容器的长度为num,若容器变长,则以elem值填充新位置。 //如果容器变短,则末尾超出容器长度的元素被删除
2.4 插入删除元素
函数原型:
push_back(ele);
//尾部插入元素elepop_back();
//删除最后一个元素insert(const_iterator pos, ele);
//迭代器指向位置pos插入元素eleinsert(const_iterator pos, int count,ele);
//迭代器指向位置pos插入count个元素eleerase(const_iterator pos);
//删除迭代器指向的元素erase(const_iterator start, const_iterator end);
//删除迭代器从start到end之间的元素clear();
//删除容器中所有元素
2.5 数据存取
函数原型:
at(int idx);
//返回索引idx所指的数据operator[];
//返回索引idx所指的数据front();
//返回容器中第一个数据元素back();
//返回容器中最后一个数据元素
2.7 交换 swap()
函数原型:
swap(vec);
// 将vec与本身的元素互换
void test03()
{
vector<int>v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
printVector(v1);
vector<int>v2;
for (int i = 10; i > 0; i--)
{
v2.push_back(i);
}
printVector(v2);
//互换容器
cout << "互换后" << endl;
v1.swap(v2);
printVector(v1);
printVector(v2);
}
swap收缩内存空间,减小capacity
//实际用途
void test04()
{
vector<int> v;
for (int i = 0; i < 100000; i++) {
v.push_back(i);
}
cout << "v的容量为:" << v.capacity() << endl;
cout << "v的大小为:" << v.size() << endl;
v.resize(3);
cout << "v的容量为:" << v.capacity() << endl;
cout << "v的大小为:" << v.size() << endl;
//收缩内存
vector<int>(v).swap(v); //匿名对象
cout << "v的容量为:" << v.capacity() << endl;
cout << "v的大小为:" << v.size() << endl;
}
resize只能改变size的值;
拷贝构造可以减小capacity
void test05()
{
vector<int> v;
for (int i = 0; i < 100; i++) {
v.push_back(i);
}
cout << "v的容量为:" << v.capacity() << endl;
cout << "v的大小为:" << v.size() << endl;
vector<int> v1(v);
cout << "v1的容量为:" << v1.capacity() << endl;
cout << "v1的大小为:" << v1.size() << endl;
v.resize(30);
cout << "v的容量为:" << v.capacity() << endl;
cout << "v的大小为:" << v.size() << endl;
vector<int> v2(v);
cout << "v2的容量为:" << v2.capacity() << endl;
cout << "v2的大小为:" << v2.size() << endl;
}
2.8 vector预留空间
功能描述:
- 减少vector在动态扩展容量时的扩展次数
函数原型:
reserve(int len);
//容器预留len个元素长度,预留位置不初始化,元素不可访问。
3 习题
3.14
void q3_14(){
int i;
vector<int> v;
while(cin>>i)
v.push_back(i);
}
3.15
void q3_15(){
string s;
vector<string> v;
while(cin>>s)
v.push_back(s);
}
3.17
void q3_17() {
string s;
char c1;
vector<string> v;
while ((cin >> s).get(c1)) {
if (c1 == '\n')
break;
v.push_back(s);
}
for (auto &i : v) {
for(auto &c :i)
c=toupper(c);
}
for (auto &i : v)
cout << i << endl;
}
void q3_17() {
vector<string> vctr;
string s;
decltype(vctr.size()) index = 0;
while (cin >> s){
for (auto& c : s)
c = toupper(c);
vctr.push_back(s);
cout << vctr[index] << endl;
index += 1;
}
}
3.19
vector<int> v(10,42);
vector<int> v{42, 42, 42, 42, 42, 42, 42, 42, 42, 42};
3.20
(网上找了一下怎么跳出cin的那个while循环)
void q3_20(){
int s;
char c1;
vector<int> v;
while ((cin >> s).get(c1)) {
v.push_back(s);
if (c1 == '\n')
break;
}
size_t size = v.size();
for (auto i = 0; i<size - 1; ++i) {
cout << v[i] + v[i + 1]<<" ";
}
cout << endl;
for (auto i = 0; i < size / 2; ++i) {
cout << v[i] + v[size - i - 1] << " ";
}
}