【C++】STL浅谈vector容器与迭代器

(一)STL概念

STL是standard template library的首字母缩写,是标准模板库
思想:泛型编程(基于函数模板,类模板实现)、提高复用性

STL分为:容器、算法、迭代器;容器和算法之间通过迭代器无缝连接

STL的六大组件:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器

(1)STL的六大组件详细功能如下:

名称 功能
容器 vector、list、deque、set、map等存放数据的结构
算法 sort、find、copy、for_each等常用算法
迭代器 使用算法控制容器中的数据
仿函数 类似函数,算法的某种策略
适配器 修饰容器、仿函数、迭代器的一种接口
空间配置器 负责空间的配置和管理

注:

  • 算法需要使用迭代器才能对容器起作用
  • 每种容器都有自己专属的迭代器;

(2)迭代器(指针类型)的种类:

种类 功能 支持运算
输入迭代器 只读访问 ++、 ==、 !=
输出迭代器 只写访问 ++
前向迭代器 读写,向前推进迭代器 ++、==、!=
双向迭代器 读写,向前向后操作 ++、–
随机访问迭代器 读写,可访问任意数据 ++、–、[n]、-n、<、>、<=、>=

(二)结合使用vector和迭代器

(1)第一种:打印vector中的元素

#include <iostream>
#include <vector>
using namespace std;

void ShowTest1()
{
    
    
	vector<int> vc;
	vc.push_back(1);
	vc.push_back(2);
	vc.push_back(3);
	vc.push_back(4);
	//定义两个迭代器分别指向第一个元素、最后一个元素+1的位置
	vector<int>::iterator itBegin = vc.begin();
	vector<int>::iterator itEnd = vc.end();
	while (itBegin != itEnd)
	{
    
    
		cout << *itBegin++ << endl;
	}
}

(2)第二种:

void ShowTest2()
{
    
    
	vector<int> vc;
	vc.push_back(1);
	vc.push_back(2);
	vc.push_back(3);
	vc.push_back(4);
	for(vector<int>::iterator it = vc.begin(); it != vc.end(); it++)
	{
    
    
		cout << *it<< endl;
	}
	
}

(3)第三种:使用标准算法头文件中的for_each函数

#include <iostream>
#include <vector>
#include <algorithm> //标准算法头文件

void ShowTest(int val)
{
    
    
	cout << val << endl;
}

int main()
{
    
    
	vector<int> vc;
	vc.push_back(1);
	vc.push_back(2);
	vc.push_back(3);
	vc.push_back(4);

	for_each(vc.begin(), vc.end(), ShowTest);
	return 0;
}

对于第三种我们看看for_each的部分源码是如何实现的:

//模板类型_Init 和_Fn
template <class _InIt, class _Fn>
_Fn for_each(_InIt _First, _InIt _Last, _Fn _Func) 
{
    
     // perform function for each element [_First, _Last)
	//为每个元素执行函数
	//检验范围
    _Adl_verify_range(_First, _Last);
    //首元素
    auto _UFirst = _Get_unwrapped(_First);
    //尾元素后一位地址
    const auto _ULast = _Get_unwrapped(_Last);
    for (; _UFirst != _ULast; ++_UFirst) {
    
    
        _Func(*_UFirst);
    }

    return _Func;
}

通过源码看出,其实for_each的实现和第一种的方式大同小异。

(4)使用vector存放自定义类型并用迭代器输出每个元素

#include <iostream>
#include <vector>
#include <string>
using namespace std;

class User
{
    
    
public:
	User(string name, int age)
	{
    
    
		_name = name;
		_age = age;
	}


	string _name;
	int _age;

};

void Test()
{
    
    
	vector<User> vc;
	User u1("HuTao", 16);
	User u2("XiangLing", 18);
	User u3("ChongYun", 19);
	User u4("XingQiu", 18);


	vc.push_back(u1);
	vc.push_back(u2);
	vc.push_back(u3);
	vc.push_back(u4);

	for (vector<User>::iterator it = vc.begin(); it != vc.end(); it++)
	{
    
    
		cout <<"name:" <<it->_name << " "<<"age :"<< it->_age <<endl;
	}

}

int main()
{
    
    
	Test();
	return 0;
}

结果:
在这里插入图片描述

(5)假设在(4)的基础上,我们将所有的vector中的User类型换成User*,该如何打印呢

分析:

  • 上面有提过其实迭代器就是一个泛型的指针,可以是任意合法类型,指向vector(容器)中的任意一个元素的地址,逻辑图如下:
    在这里插入图片描述
  • 那么将所有的vector换成vector<User*>也就很好理解了, 此时的迭代器就是一个二级指针
    逻辑图如下:
    在这里插入图片描述
  • 所以vector换成User*类型,就得使用两次解引用(*(*it))._name 或者(*it)->_name来访问容器中的元素了
void Test()
{
    
    
	User u1("HuTao", 16);
	User u2("XiangLing", 18);
	User u3("ChongYun", 19);
	User u4("XingQiu", 18);

	vector<User*> vc;
	vc.push_back(&u1);
	vc.push_back(&u2);
	vc.push_back(&u3);
	vc.push_back(&u4);

	for (vector<User*>::iterator it = vc.begin(); it != vc.end(); it++)
	{
    
    
		cout << "name:" << (*(*it))._name << " " << "age :" << (*it)->_age << endl;
	}

}

结果:
在这里插入图片描述

(三)vector容器的嵌套使用

嵌套使用比如:vector<vector<int>> vct;其中vct类似一个int类型的二维数组的结构;像这种情况我们如何使用迭代器去访问vct容器中的每一个元素呢?
逻辑图如下:
在这里插入图片描述
代码如下:

#include <iostream>
#include <vector>
using namespace std;

//输出所有的元素
void ShowAllItem( vector<vector<int> >* pvct)
{
    
    
	if (pvct == NULL) return;
	vector < vector<int> >::iterator p_itBegin = pvct->begin();
	vector < vector<int> >::iterator p_itEnd = pvct->end();
	
	while (p_itBegin != p_itEnd)
	{
    
    
		vector<int>::iterator itBegin = p_itBegin->begin();
		vector<int>::iterator itEnd = p_itBegin->end();
		while (itBegin != itEnd)
		{
    
    
			cout << *itBegin << " ";
			itBegin++;
		}
		cout << endl;
		p_itBegin++;
	}

}
//向vector<int>类型的容器中添加int类型数据
void Insert_Vc(vector<int>* vc, int data)
{
    
    
	if (vc == NULL) return;
	vc->push_back(data);
}

void Test()
{
    
    

	vector<int> vc1;
	vector<int> vc2;
	vector<int> vc3;
	for (int i = 1; i < 4; i++)
	{
    
    
		Insert_Vc(&vc1, i);
		Insert_Vc(&vc2, i * 10);
		Insert_Vc(&vc3, i * 100);
	}

	//向vector<vector<int>>的容器中添加vector<int>数据
	vector< vector<int> > vct;

	vct.push_back(vc1);
	vct.push_back(vc2);
	vct.push_back(vc3);

	ShowAllItem(&vct);
}
int main()
{
    
    
	Test();
	return 0;
}

vs中的逻辑图:
在这里插入图片描述
运行结果:
在这里插入图片描述

Guess you like

Origin blog.csdn.net/xiaoxiaoguailou/article/details/121357765