基于for循环高效率遍历容器方法 C++

1、常用的iterator遍历容器

std::vector<int> vec {1,2,3,4,5,6,7,8,9,10};  
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it)  
    cout << *it<<endl;  
//需注意:遍历时,++it的效率是大于it++的

上述方法,需要明确给出容器的开始和结束条件,以遍历整个容器;

2、C++11引入的auto遍历容器(不适用于数组)

此方法,无需给出容器的开始和结束条件,就可遍历整个容器;此方法遍历容器,效率跟高;

通用格式:

for(auto temp : 容器name)
{  
    cout<<temp<<endl;   
}
//temp就是容器中一个元素,数据类型与容器中元素一致,即容器中元素是什么,temp就是什么

 注意:在上述对容器的遍历是只读的,也就是说遍历的值是不可修改的,如果需要修改其中元素,需声明为auto &

原理:

for(auto it = gate.get_output().begin(), ;it != gate.get_output().end();it++)
{
    temp = (*it);   //这里,其实已经有了两份内存,temp调用了一次
//这个类对应的构造函数调用构造函数会花费时间,而引用避免了调用构造函数;
    // 当然 如果遍历的容器本来就是int类型或者指针类型的(即数据类型并非类),那么二者时间差不多;
    // 习惯上最好用引用,可以节省空间
    循环体实质内容;
}

示例:

#include<iostream>
using namespace std;
#include<vector>
int main()
{
	vector<int> vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	for(auto &temp:vec)
	{
		temp=temp*10;
	}	
	for(auto temp: vec)
	{
		cout<<temp<<"  ";
	}
	cout<<endl;
	return 0;
}

程序运行结果:

 3、auto遍历map容器

在遍历容器的时候,auto自动推导的类型是容器的value_type类型,而不是迭代器,而map中的value_type是std::pair,也就是说val的类型是std::pair类型的,因此需要使用vec.first,vec.second来访问数据;

#include<iostream>
using namespace std;
#include<map>
int main()
{
	map<string,int> vec{ {"aa",1},{"bb",2},{"cc",3} };
	for(auto &temp:vec)
	{
		temp.second=temp.second*10;
	}	
	for(auto temp: vec)
	{
		cout<<temp.first<<"  "<<temp.second;
		cout<<endl;
	}
	cout<<endl;
	return 0;

}

程序运行结果:

 4、使用注意

  • 容器本身的约束,导致不可修改容器元素:

比如set的容器内的元素本身有容器的特性就决定了其元素是只读的,哪怕的使用了引用类型来遍历set元素,也是不能修改器元素的,举例如下:

set<int> vec = { 1, 2, 3, 4, 5, 6 };  
for (auto &temp : vec)  
    cout << temp++ << endl;  

上述代码定义了一个set,使用引用类型遍历set中的元素,然后对元素的值进行修改,该段代码编译失败:error C3892: 'n' : you cannot assign to a variable that is const。同样对于map中的first元素也是不能进行修改的

  • 当冒号后不是容器而是一个函数则冒号后面的函数调用,函数仅会被调用一次
#include <iostream>
#include <set>
using namespace std;
 
set<int> vec = { 11, 22, 33, 44, 55, 66 };
const set<int> getSet()
{
	cout << "--------GetSet----------" << endl;
	return vec;
}
 
int main()
{
	for (auto temp : getSet())
		cout << temp << endl;
 
	system("pause");
	return 0;
}

程序运行结果:

  •  不要在for循环中遍历容器时修改容器
#include <iostream>
#include <vector>
using namespace std;
 
vector<int> vec = { 1, 2, 3, 4, 5, 6 };
 
int main()
{
	for (auto temp : vec)
	{
		cout << temp << endl;
		vec.push_back(100);
	}
	return 0;
}

上述代码在遍历vector时,在容器内插入一个元素100,运行上述代码程序崩溃;

原因:在遍历容器的时候,在容器中插入一个元素导致迭代器失效了,因此,基于范围的for循环和普通的for循环一样,在遍历的过程中如果修改容器,都将造成迭代器失效;

总结:在基于for循环遍历容器的过程中,可以通过引用&修改容器中的元素,但是不可对容器进行修改;

  • 9
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值