C++进阶-STL vector容器的简单认识

STL vector容器的简单认识

    • vector 存放内置数据类型
    • vector 存放自定义的数据类型
    • vector容器嵌套容器
    • vector 基本概念
    • vector的构造函数
    • vector容器赋值操作
    • vector容器容量和大小
    • vector容器插入和删除
    • vector容器数据存取
    • vector容器互换容器
    • vector容器预留空间

vector 存放内置数据类型

容器vector
算法for_each
迭代器vector::iterator

#include 
#include 
#include 
//标准算法的头文件
#include 
using namespace std;

void print(int val)
{
	cout << val << " ";
}

int main()
{
	vector<int> v;
	//向容器中插入数据
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	//通过迭代器访问容器中的数据
	vector<int>::iterator itBegin = v.begin(); //起始迭代器 指向容器第一个元素
	vector<int>::iterator itEnd = v.end(); //结束迭代器 指向容器中最后一个元素的下一个位置

	//第一种遍历方式
	while (itBegin != itEnd)
	{
		cout << *itBegin << " ";
		itBegin++;
	}

	cout << endl;

	//第二种遍历方式
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}

	cout << endl;

	//第三种遍历方式 利用STL中提供的遍历算法
	for_each(v.begin(), v.end(), print);
}

上文中提到了三种遍历方式:

  • 第一种遍历方式
vector<int>::iterator itBegin = v.begin(); //起始迭代器 指向容器第一个元素
vector<int>::iterator itEnd = v.end(); //结束迭代器 指向容器中最后一个元素的下一个位置

//第一种遍历方式
while (itBegin != itEnd)
{
	cout << *itBegin << " ";
	itBegin++;
}
  • 第二种遍历方式
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
	cout << *it << " ";
}
  • 第三种遍历方式
for_each(v.begin(), v.end(), print);

其中print是一个回调函数,可以拿到每一个值,其具体实现如下:
C++进阶-STL vector容器的简单认识_第1张图片
即内部还是一个循环,每循环一次,调用回调函数并传回当前循环的值信息

vector 存放自定义的数据类型

  • vector 存放自定义数据类型
#include 
#include 
#include 
//标准算法的头文件
#include 
using namespace std;

class Person
{
private:
	string m_name;
	int m_age;
public:
	Person(string name, int age)
	{
		this->m_name = name;
		this->m_age = age;
	}
	void printf()
	{
		std::cout << "name= " << this->m_name << " age= " << this->m_age << std::endl;
	}
	static void print(Person& person)
	{
		std::cout << "name= " << person.m_name << " age= " << person.m_age << std::endl;
	}
};

int main()
{
	vector<Person> vP;
	Person person("张三", 36);
	vP.push_back(person);

	//第一种遍历方式
	vector<Person>::iterator itBegin = vP.begin();
	vector<Person>::iterator itEnd = vP.end();
	while (itBegin != itEnd)
	{
		itBegin->printf();
		itBegin++;
	}

	//第二种遍历方式
	for (vector<Person>::iterator it = vP.begin(); it != vP.end(); it++)
	{
		it->printf();
	}

	//第三种遍历方式
	for_each(vP.begin(), vP.end(), Person::print);
}
  • vector 存放的自定义数据类型指针
#include 
#include 
#include 
//标准算法的头文件
#include 
using namespace std;

class Person
{
private:
	string m_name;
	int m_age;
public:
	Person(string name, int age)
	{
		this->m_name = name;
		this->m_age = age;
	}
	void printf()
	{
		std::cout << "name= " << this->m_name << " age= " << this->m_age << std::endl;
	}
	static void print(Person& person)
	{
		std::cout << "name= " << person.m_name << " age= " << person.m_age << std::endl;
	}
};

int main()
{
	vector<Person*> vP;
	Person person("张三", 36);
	vP.push_back(&person);

	//第一种遍历方式
	vector<Person*>::iterator itBegin = vP.begin();
	vector<Person*>::iterator itEnd = vP.end();
	while (itBegin != itEnd)
	{
		(*itBegin)->printf();
		itBegin++;
	}

	//第二种遍历方式
	for (vector<Person*>::iterator it = vP.begin(); it != vP.end(); it++)
	{
		(*it)->printf();
	}
}

vector容器嵌套容器

容器嵌套可以看作多维数组来处理

#include 
#include 
#include 
//标准算法的头文件
#include 
using namespace std;

class Person
{
private:
	string m_name;
	int m_age;
public:
	Person(string name, int age)
	{
		this->m_name = name;
		this->m_age = age;
	}
	void printf()
	{
		std::cout << "name= " << this->m_name << " age= " << this->m_age << std::endl;
	}
	static void print(Person& person)
	{
		std::cout << "name= " << person.m_name << " age= " << person.m_age << std::endl;
	}
};

int main()
{
	vector<vector<Person>> v;
	vector<Person> vp;
	Person p("张三", 1);
	vp.push_back(p);
	Person p_2("张三", 1);
	vp.push_back(p_2);
	//小容器插入到大容器中
	v.push_back(vp);

	for (vector<vector<Person>>::iterator it = v.begin(); it != v.end(); it++)
	{
		for (vector<Person>::iterator pit = (*it).begin(); pit != (*it).end(); pit++)
		{
			(*pit).printf();
		}
	}
}

vector 基本概念

vector数据结构和数组非常相似,也成为单端数组

vector与数组的不同之处在于数组是静态空间,而vector是动态扩展的

vector动态扩展:不是在原有空间之后续接新空间,而是寻找更大的内存空间,然后将原来的数据拷贝到新空间,释放原空间

C++进阶-STL vector容器的简单认识_第2张图片
vector容器的迭代器是支持随机访问的迭代器

vector的构造函数

  • vector v; 采用模板实现类是按,默认的构造函数
vector<string> v;
  • vector(v.begin(), v.end()); 将v[begin(), end()) 区间中的元素拷贝给本身
vector<string> v;
for (int i = 0; i < 10; i++)
{
	v.push_back(i + "");
}
vector<string> v2(v.begin(), v.end());
  • vector(n, elem); 构造函数将n个elem拷贝给本身
vector<int> v(10, 100);
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
	std::cout << *it << " ";
}

演示效果

  • vector(const vector& vec); 拷贝构造函数
vector<string> v;
vector<string> v_copy(v);

vector容器赋值操作

  • vector& operator=(const vector &vec); 重载等号操作符
vector<int> v(10, 100);
vector<int> v2;
v2 = v;
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{
	std::cout << *it << " ";
}
  • assign(beg, end); 将[beg, end] 区间中的数据拷贝赋值给本身
vector<int> v(10, 100);
vector<int> v2;
v2.assign(v.begin(), v.end());
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{
	std::cout << *it << " ";
}
  • assign(n, elem); 将n个elem拷贝给本身
vector<int> v;
v.assign(2, 5);
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
	std::cout << *it << " ";
}

演示结果

vector容器容量和大小

  • empty(); 判断容器是否为空
vector<int> v(10, 100);
std::cout << "容器v是否为空:" << v.empty() << std::endl;
  • capacity(); 容器的容量
vector<int> v(10, 100);
v.pop_back();
std::cout << "容器v的容量:" << v.capacity() << std::endl;
  • size(); 返回容器中元素的个数
vector<int> v(10, 100);
v.pop_back();
std::cout << "容器v的元素数量:" << v.size() << std::endl;
  • resize(int num); 重新指定容器的长度为num,若容器变长,则用默认值填充新位置,如果容器变短,则末尾超出容器长度的元素将被删除
vector<int> v2(10, 100);
v2.resize(5);
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{
	std::cout << *it << " ";
}

运行结果

  • resize(int num, elem); 重新指定容器的长度为num, 若容器变长,则以elem值填充新位置,如果容器变短,则末尾超出容器长度的元素将被删除
vector<int> v2(10, 100);
v2.resize(15, 99);
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{
	std::cout << *it << " ";
}

演示结果

vector容器插入和删除

  • push_back(ele); 尾部插入元素ele
vector<int> v2;
v2.push_back(12);
  • pop_back(); 删除最后一个元素
vector<int> v2;
v2.pop_back();
  • insert(const_iterator pos, ele); 迭代器指向位置pos插入元素ele
vector<int> v2;
for (int i = 0; i < 10; i++)
{
	v2.push_back(i);
}
v2.insert(v2.begin(), 1);
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{
	std::cout << *it << " ";
}
  • insert(const_iterator pos, int count, ele); 迭代器只想位置pos插入count个元素ele
vector<int> v2;
for (int i = 0; i < 10; i++)
{
	v2.push_back(i);
}
v2.insert(v2.begin(), 10, 1);
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{
	std::cout << *it << " ";
}

在这里插入图片描述

  • erase(const_iterator pos); 删除迭代器指向的元素
vector<int> v2;
for (int i = 0; i < 10; i++)
{
	v2.push_back(i);
}
v2.erase(v2.begin());
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{
	std::cout << *it << " ";
}
  • erase(const_iterator start, const_iterator end); 删除迭代器start到end之间的元素
vector<int> v2;
for (int i = 0; i < 10; i++)
{
	v2.push_back(i);
}
v2.erase(v2.begin(), v2.end());
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{
	std::cout << *it << " ";
}
  • clear(); 删除容器中所有的元素
vector<int> v2(10, 100);
v2.clear();
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{
	std::cout << *it << " ";
}

输出为空

vector容器数据存取

  • at(int idx); 返回索引idx所指的数据
vector<int> v2;
for (int i = 0; i < 10; i++)
{
	v2.push_back(i);
}
std::cout << v2.at(4) << std::endl;
  • operator[]; 返回索引idx所指的数据
vector<int> v2;
for (int i = 0; i < 10; i++)
{
	v2.push_back(i);
}
std::cout << v2[4] << std::endl;
  • front(); 返回容器中的第一个数据元素
vector<int> v2;
for (int i = 0; i < 10; i++)
{
	v2.push_back(i);
}
std::cout << v2.font() << std::endl;
  • back(); 返回容器中最后一个数据元素
vector<int> v2;
for (int i = 0; i < 10; i++)
{
	v2.push_back(i);
}
std::cout << v2.back() << std::endl;

vector容器互换容器

  • swap(vec); 将vec与本身的元素互换
vector<int> v2;
for (int i = 0; i < 10; i++)
{
	v2.push_back(i);
}
vector<int> v1;
for (int i =11; i < 20; i++)
{
	v1.push_back(i);
}
v2.swap(v1);
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{
	std::cout << *it << " ";
}
std::cout << std::endl;
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
{
	std::cout << *it << " ";
}

执行结果
实际上,swap 可以用于收缩内存空间,可以重新指定一个跟实际的vector相同的数量的vector,然后交换值,用于缩减内存

vector<int> v2(1000, 1);
v2.resize(10);
std::cout << "v2.capacity() = " << v2.capacity() << std::endl;
std::cout << "v2.size() = " << v2.size() << std::endl;
vector<int> v1(v2);
std::cout << "v1.capacity() = " << v1.capacity() << std::endl;
std::cout << "v1.size() = " << v1.size() << std::endl;
v2.swap(v1);
std::cout << "交换后 v2.capacity() = " << v2.capacity() << std::endl;
std::cout << "交换后 v2.size() = " << v2.size() << std::endl;

C++进阶-STL vector容器的简单认识_第3张图片

vector容器预留空间

该功能可以减少vector在动态扩展容量时的扩展次数

  • reserve(int len); 容器预留len个元素长度,预留位置不初始化,元素不可访问
#include 
#include 
using namespace std;

int main()
{
	vector<int> v;
	int num = 0;
	int* p = NULL;
	for (int i = 0; i < 10000; i++)
	{
		v.push_back(i);
		if (p != &v[0])
		{
			p = &v[0];
			num++;
		}
	}
	std::cout << "vector初始化10000个数据,迁移了内存次数为:" << num << std::endl;

	vector<int> v2;
	v2.reserve(1000);
	int num2 = 0;
	int* p2 = NULL;
	for (int i = 0; i < 10000; i++)
	{
		v2.push_back(i);
		if (p2 != &v2[0])
		{
			p2 = &v2[0];
			num2++;
		}
	}
	std::cout << "vector v2 预留1000个位置后 初始化10000个数据,迁移了内存次数为:" << num2 << std::endl;
}

执行结果

你可能感兴趣的:(C++入门与进阶内容专栏,c++,开发语言)