实战c++中的vector系列--vector的遍历(stl算法、vector迭代器(不要在循环中推断不等于end())、operator[])
遍历一个vector容器有非常多种方法。使用起来也是仁者见仁。
通过索引遍历:
for (i = 0; i<v.size(); i++)
{
cout << v[i] << " ";
}
迭代器遍历:
for (vInt::const_iterator iter = v.begin(); iter != v.end();iter++)
{
cout << *iter << " ";
}
算法遍历:
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
非常多书上推荐的是使用算法进行遍历。
写了一个简单的程序对上面的三种方法进行了比較:
#include<iostream>
#include<vector>
#include<iterator>
#include<algorithm>
#include<time.h>
#include<windows.h>
using namespace std;
typedef vector<int> vInt;
void print_vec_operator(const vInt & v)//方法一,採用下标訪问
{
int i;
for (i = 0; i<v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
}
void print_vec_iterator(const vInt &v)//方法二,採用迭代器訪问
{
for (vInt::const_iterator iter = v.begin(); iter != v.end();iter++)
{
cout << *iter << " ";
}
cout << endl;
}
void print_vec_algorithm(const vInt &v)//方法三。将容器的内容拷贝到cout绑定的迭代器
{
copy(v.begin(), v.end(), ostream_iterator<int>(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<iostream>
#include<vector>
#include<iterator>
#include <algorithm>
#include <functional>
#include<windows.h>
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<void, AAA>(&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()的时候,都要进行又一次构造一个迭代器并进行返回。这样当然减少的效率。
实战c++中的vector系列--vector的遍历(stl算法、vector迭代器(不要在循环中推断不等于end())、operator[])的更多相关文章
- spice在桌面虚拟化中的应用系列之三(USB映射实现,SSL加密,密码认证,多客户端支持)
本系列其它文章 spice在桌面虚拟化中的应用系列之一(spice简介,性能优化等) spice在桌面虚拟化中的应用系列之二(Linux平台spice客户端的编译安装,支持USB映射) 1.spice ...
- 循环中不要放入openSession()
for(Shop s:list) { System.out.println(s.getName()); String sql="select shopId,sum(ele_bank+ele_ ...
- 深入浅出:了解for循环中保留i值得方法
一.保留i值 通常情况下,因为一些效果我们需要获取到for循环中的i的值,但是往往拿到的都是最后一个i的值.下面介绍几种方法可以获取到i的值 1.自定义属性: arr[i].index = i; 以 ...
- 实战c++中的string系列--std:vector 和std:string相互转换(vector to stringstream)
string.vector 互转 string 转 vector vector vcBuf;string stBuf("Hello DaMao!!!");----- ...
- 实战c++中的vector系列--vector应用之STL的find、find_if、find_end、find_first_of、find_if_not(C++11)
使用vector容器,即避免不了进行查找,所以今天就罗列一些stl的find算法应用于vector中. find() Returns an iterator to the first element ...
- 实战c++中的vector系列--构造、operator=和assign差别
vector或许是实际过程中使用最多的stl容器.看似简单,事实上有非常多技巧和陷阱. 着重看一看vector的构造,临时依照C++11: default (1) explicit vector (c ...
- 实战c++中的vector系列--正确释放vector的内存(clear(), swap(), shrink_to_fit())
关于vector已经写的差不多了,似乎要接近尾声了,从初始化到如何添加元素再到copy元素都有所涉及,是时候谈一谈内存的释放了. 是的,对于数据量很小的vector,完全没必要自己进行主动的释放,因为 ...
- 实战c++中的vector系列--copy set to vector(别混淆了reserve和resize)
stl算法中有个copy函数.我们能够轻松的写出这种代码: #include <iostream> #include <algorithm> #include <vect ...
- 【实战Java高并发程序设计6】挑战无锁算法:无锁的Vector实现
[实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference [实战Java高并发程序设计 3]带有时间戳的对象 ...
随机推荐
- nyoj 题目6 喷水装置
喷水装置(一) 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以 ...
- hdu5985[概率dp] 2016青岛icpc现场赛
#include <bits/stdc++.h> using namespace std; ][]; ][]; ][]; ]; ]; int T, n; double fastpow(do ...
- 利用jQuery无缝滚动插件liMarquee实现图片(链接)和文字(链接)向右无缝滚动(兼容ie7+)
像新闻类的版块经常要求一条条的新闻滚动出现,要实现这种效果,可以使用jQuery无缝滚动插件liMarquee. 注意: 1. 它的兼容性是IE7+,及现代浏览器. 2. 引用的jquery的版本最好 ...
- luogu3723 [AH2017/HNOI2017]礼物 【NTT】
题目 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一 个送给她.每个手环上各有 n 个装饰物,并且每个装饰物都有一定的亮度.但是在她生日的前一天, ...
- codevs 1081 线段树练习 2 区间更新 单点查询 无lazy
题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有数都增加X 2:询问第i个数是什么? 输入描述 Input Description 第一行一个正整数n,接下来n行n ...
- git merge / rebase 分支的新建与合并
merge https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5% ...
- 如何用jquery获得td里边的内容
jQuery 中使用 text() 或者 html() 函数可以获取td的内容: $("td").text(); // 或者 $("td").html(); ...
- CODEVS【3372】选学霸
题目描述 Description 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一部分没有,同学们就会抗议.所以老师想请你帮他求出他该选多少学霸,才能既不让同 ...
- RowFilter 对于已获取到的dataset进行过滤
原文发布时间为:2009-11-12 -- 来源于本人的百度文章 [由搬家工具导入] DataView的属性RowFilter使用方法 p.s. 重点在于DataView是DateTable相关联的一 ...
- 高级参数绑定(数组和List绑定)
1.绑定数组: (1) 需求 在商品列表页面选中多个商品,然后删除. (2). 需求分析 功能要求商品列表页面中的每个商品前有一个checkbok,选中多个商品后点击删除按钮把商品id传递给Contr ...