STL_VECTOR

STL_VECTOR

1. vector:

1.1 vector 说明

vector是向量类型,可以容纳许多类型的数据,因此也被称为容器

(可以理解为动态数组,是封装好了的类)

进行vector操作前应添加头文件#include

1.2 vector初始化:

方式1.

//定义具有10个整型元素的向量(尖括号为元素类型名,它可以是任何合法的数据类型),不具有初值,其值不确定
vectora(10);
12

方式2.

//定义具有10个整型元素的向量,且给出的每个元素初值为1
vectora(10,1);

方式3.

//用向量b给向量a赋值,a的值完全等价于b的值
vectora(b);

方式4.

//将向量b中从0-2(共三个)的元素赋值给a,a的类型为int型
vectora(b.begin(),b.begin+3);

方式5.

 //从数组中获得初值
int b[7]={1,2,3,4,5,6,7};
vector a(b,b+7);

1.3 vector对象的常用内置函数使用(举例说明)

#include
vector a,b;
//b为向量,将b的0-2个元素赋值给向量a
a.assign(b.begin(),b.begin()+3);
//a含有4个值为2的元素
a.assign(4,2);
//返回a的最后一个元素
a.back();
//返回a的第一个元素
a.front();
//返回a的第i元素,当且仅当a存在
a[i];
//清空a中的元素
a.clear();
//判断a是否为空,空则返回true,非空则返回false
a.empty();
//删除a向量的最后一个元素
a.pop_back();
//删除a中第一个(从第0个算起)到第二个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+3(不包括它)结束
a.erase(a.begin()+1,a.begin()+3);
//在a的最后一个向量后插入一个元素,其值为5
a.push_back(5);
//在a的第一个元素(从第0个算起)位置插入数值5,
a.insert(a.begin()+1,5);
//在a的第一个元素(从第0个算起)位置插入3个数,其值都为5
a.insert(a.begin()+1,3,5);
//b为数组,在a的第一个元素(从第0个元素算起)的位置插入b的第三个元素到第5个元素(不包括b+6)
a.insert(a.begin()+1,b+3,b+6);
//返回a中元素的个数
a.size();
//返回a在内存中总共可以容纳的元素个数
a.capacity();
//将a的现有元素个数调整至10个,多则删,少则补,其值随机
a.resize(10);
//将a的现有元素个数调整至10个,多则删,少则补,其值为2
a.resize(10,2);
//将a的容量扩充至100,
a.reserve(100);
//b为向量,将a中的元素和b中的元素整体交换
a.swap(b);
//b为向量,向量的比较操作还有 != >= > <= <
a==b;

2. 顺序访问vector的几种方式,举例说明

2.1. 对向量a添加元素的几种方式

1.向向量a中添加元素

vectora;
for(int i=0;i<10;++i){a.push_back(i);}

2.从数组中选择元素向向量中添加

int a[6]={1,2,3,4,5,6};
vector b;
for(int i=0;i<=4;++i){b.push_back(a[i]);}

3.从现有向量中选择元素向向量中添加

int a[6]={1,2,3,4,5,6};
vectorb;
vectorc(a,a+4);
for(vector::iterator it=c.begin();it

4.从文件中读取元素向向量中添加

ifstream in("data.txt");
vectora;
for(int i;in>>i){a.push_back(i);}

5.常见错误赋值方式

vectora;
for(int i=0;i<10;++i){a[i]=i;}//下标只能用来获取已经存在的元素

2.2 从向量中读取元素

1.通过下标方式获取

int a[6]={1,2,3,4,5,6};
vectorb(a,a+4);
for(int i=0;i<=b.size()-1;++i){cout<

2.通过迭代器方式读取

 int a[6]={1,2,3,4,5,6};
 vectorb(a,a+4);
 for(vector::iterator it=b.begin();it!=b.end();it++){cout<<*it<<"  ";}

3.vector iterator的使用

1.begin + end(重点)

获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下

一个位置的iterator/const_iterator

2.rbegin + rend

获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置

的reverse_iterator

代码实现

#include
#include
using namespace std;
void PrintVector(const vector& v)
{
	vector::const_iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}
void main()
{
	//使用push back插入四个数据
	vector v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	//使用迭代器进行遍历打印
	vector::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	//使用迭代器进行修改内容
	it = v.begin();
	while (it != v.end())
	{
		*it *= 3;
		++it;
	}
	PrintVector(v);
	//使用反向迭代器进行遍历打印
	vector::reverse_iterator rit = v.rbegin();
	while (rit != v.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
}

4.vector空间增长问题

size 获取数据个数

capacity 获取容量大小

empty 判断是否为空

resize 改变vector的size

reserve 改变vector放入capacity

说明:reserve只负责开辟空间,如果确定知道需要多少空间,reserve可以缓解vector增容的代价缺陷问题。

resize在开空间的同事还会进行初始化,影响size。

代码实现

void main()
{
	size_t sz;
	std::vector foo;
	sz = foo.capacity();
	std::cout << "making foo grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		foo.push_back(i);
		if (sz != foo.capacity())
		{
			sz = foo.capacity();
			std::cout << "capacity changed:" << sz << '\n';
		}
	}
	std::vector bar;
	sz = bar.capacity();
	bar.reserve(100); 
	std::cout << "making bar grow:\n";
	for (int i = 0; i < 100; ++i) {
		bar.push_back(i);
		if (sz != bar.capacity()) {
			sz = bar.capacity();
			std::cout << "capacity changed: " << sz << '\n';
		}
	}
}

5.vector增删查改

push_bacK 尾插

pop_back 尾删

find 查找

insert 在position之前插入val

erase 删除position位置的数据

swap 交换两个vector的数据空间

operator[] 像数组一样访问

push_back/pop_back代码实现

void main()
{
	int a[] = { 1, 2, 3, 4 };
	vector v(a, a + sizeof(a) / sizeof(int));
	vector::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	v.pop_back();
	v.pop_back();//删除操作
	v.push_back(5);
	it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

find / insert / erase 代码实现

void PrintVector(const vector& v)
{
	vector::const_iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}
void main()
{
	int a[] = { 1, 2, 3, 4 };
	vector v(a, a + sizeof(a) / sizeof(int));
	//使用find查找3所在位置的inerator
	vector::iterator pos = find(v.begin(), v.end(), 3);
	//在pso位置之前使用insert30
	v.insert(pos, 30);
	PrintVector(v);
	pos = find(v.begin(), v.end(), 3);
	//删除pos位置的数据
	v.erase(pos);
	PrintVector(v);
}

vector的遍历方式

void main()
{
 int a[] = { 1, 2, 3, 4 };
 vector v(a, a + sizeof(a) / sizeof(int));
 // 通过[]读写第0个位置。
 v[0] = 10;
 cout << v[0] << endl;
 // 通过[i]的方式遍历vector
 for (size_t i = 0; i < v.size(); ++i)
 cout << v[i] << " ";
 cout << endl;
 vector swapv;
 swapv.swap(v);
 cout << "v data:";
 for (size_t i = 0; i < v.size(); ++i)
 cout << v[i] << " ";
 cout << endl;
 cout << "swapv data:";
 for (size_t i = 0; i < swapv.size(); ++i)
 cout << swapv[i] << " ";
 cout<

6.vector迭代器失效问题

insert/erase导致迭代器失效

void main()
{
 int a[] = { 1, 2, 3, 4 };
 vector v(a, a + sizeof(a) / sizeof(int));
 // 使用find查找3所在位置的iterator
 vector::iterator pos = find(v.begin(), v.end(), 3);
 // 删除pos位置的数据,导致pos迭代器失效。
 v.erase(pos);
 cout << *pos << endl; // 此处会导致非法访问
 // 在pos位置插入数据,导致pos迭代器失效。
 // insert会导致迭代器失效,是因为insert可
 // 能会导致增容,增容后pos还指向原来的空间,而原来的空间已经释放了。
 pos = find(v.begin(), v.end(), 3);
 v.insert(pos, 30);
 cout << *pos << endl; // 此处会导致非法访问
 }

常见的迭代器失效

void main()
{
 int a[] = { 1, 2, 3, 4 };
 vector v(a, a + sizeof(a) / sizeof(int));
 // 实现删除v中的所有偶数
 // 下面的程序会崩溃掉,如果是偶数,erase导致it失效
 // 对失效的迭代器进行++it,会导致程序崩溃
 vector::iterator it = v.begin();
 while (it != v.end())
 {
 if (*it % 2 == 0)
 v.erase(it);
 ++it;
 }
 // 以上程序要改成下面这样,erase会返回删除位置的下一个位置
 vector::iterator it = v.begin();
 while (it != v.end())
 {
 if (*it % 2 == 0)
 it = v.erase(it);
 else
 ++it;
 }
}

你可能感兴趣的:(C++学习)