博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实战c++中的vector系列--vector的遍历(stl算法、vector迭代器(不要在循环中推断不等于end())、operator[])...
阅读量:6972 次
发布时间:2019-06-27

本文共 3058 字,大约阅读时间需要 10 分钟。

遍历一个vector容器有非常多种方法。使用起来也是仁者见仁。

通过索引遍历:

for (i = 0; i

迭代器遍历:

for (vInt::const_iterator iter = v.begin(); iter != v.end();iter++){    cout << *iter << " ";}

算法遍历:

copy(v.begin(), v.end(), ostream_iterator
(cout, " "));

非常多书上推荐的是使用算法进行遍历。

写了一个简单的程序对上面的三种方法进行了比較:

#include
#include
#include
#include
#include
#include
using namespace std;typedef vector
vInt;void print_vec_operator(const vInt & v)//方法一,採用下标訪问{ int i; for (i = 0; i
(cout, " ")); cout << endl;}int main(){ vInt v; int i; for (i = 0; i<100000; i++) { v.push_back(i); } int start_time_print_vec1 = GetTickCount(); print_vec_operator(v); int end_time_print_vec1 = GetTickCount(); int start_time_print_vec2 = GetTickCount(); print_vec_iterator(v); int end_time_print_vec2 = GetTickCount(); int start_time_print_vec3 = GetTickCount(); print_vec_algorithm(v); int end_time_print_vec3 = GetTickCount(); std::cout << (end_time_print_vec1 - start_time_print_vec1) << endl; std::cout << (end_time_print_vec2 - start_time_print_vec2) << endl; std::cout << (end_time_print_vec3 - start_time_print_vec3) << endl; return 0;}

当vector初始化10000个元素时,三种方法的效率不相上下。执行几次时间相差无几:

//输出:
//1718 operator[]
//1735 iterator
//1797 algorithm

可是当把veector初始化100000的时候,三种方法的效率就有了较大的差距:

//输出:
//20016 operator[]
//32172 iterator
//62468 algorithm

再写一个vector里放一个类:

#include
#include
#include
#include
#include
#include
class AAA{public: void MakeFull2() { }};int main(){ int nCount = 1000000; std::vector< AAA* > vAAA; vAAA.resize(nCount); for (int i = 0; i < nCount; ++i) { vAAA[i] = new AAA; } // 时间 int start, end; // 測试成员函数调用(std::vector下标訪问方式) start = GetTickCount(); size_t count = vAAA.size(); for (size_t i = 0; i < count; ++i) vAAA[i]->MakeFull2(); end = GetTickCount(); std::cout << end - start << std::endl; // 測试成员函数调用(STL算法方式) start = GetTickCount(); std::for_each(vAAA.begin(), vAAA.end(), std::mem_fun
(&AAA::MakeFull2)); end = GetTickCount(); std::cout << end - start << std::endl; // 測试成员函数调用(STL迭代器方式) start = GetTickCount(); std::vector< AAA* >::iterator itr_end = vAAA.end(); for (std::vector< AAA* >::iterator itr = vAAA.begin(); itr != itr_end; ++itr) (*itr)->MakeFull2(); end = GetTickCount(); std::cout << end - start << std::endl; // 測试成员函数调用(STL迭代器方式) start = GetTickCount(); for (std::vector< AAA* >::iterator itr = vAAA.begin(); itr != vAAA.end(); ++itr) (*itr)->MakeFull2(); end = GetTickCount(); std::cout << end - start << std::endl; return 0;}//输出://313 oprator[]//62 algorithm//422 iterator//922 iterator

再执行一次,结果为:

//296
//63
//594
//1672

这个时候使用algorithm+functional进行遍历效率最高。

个人认为下标索引的方式总是会效率高于迭代器方式。

以下分析一下两种迭代器方式。为何相差不小呢:

这就要看一下std::vector::end()的原型了:

iterator end() _NOEXCEPT{   // return iterator for end of mutable sequence    return (iterator(this->_Mylast(), &this->_Get_data()));}

就是每次推断itr != vAAA.end()的时候,都要进行又一次构造一个迭代器并进行返回。这样当然减少的效率。

转载地址:http://moasl.baihongyu.com/

你可能感兴趣的文章
v-solt插槽
查看>>
OCM_第六天课程:Section3 —》数据库可用性
查看>>
ORA-00257 archiver error. 错误的处理方法
查看>>
开发Servlet的方法(2)
查看>>
Apache mod_wsgi部署Django项目
查看>>
玲珑杯#20 C 漆黑的太阳——莫队
查看>>
MySQL数据库建立外键失败的原因总结
查看>>
网络资源收集工具编码规范
查看>>
ZOJ3778 Talented Chef(贪心)
查看>>
iOS上的反射用法
查看>>
CF1072A Palindromic Twist 思维
查看>>
Leetcode c语言-Permutations
查看>>
《javascript设计模式》阅读笔记
查看>>
JQuery基础总结上
查看>>
postgresql 备份
查看>>
Cocos2d-x调用Java 代码
查看>>
close方法
查看>>
如何为crontab调度运行的多脚本设置共享的环境变量?
查看>>
bash字符串匹配
查看>>
选择设置好ext3日志模式
查看>>