用c++11打造类似于python的range
python中的range函数表示一个连续的有序序列,range使用起来很方便,因为在定义时就隐含了初始化过程,因为只需要给begin()和end()或者仅仅一个end(),就能表示一个连续的序列。还可以指定序列产生的步长,如range(0,10,8)产生的序列为[0, 8], 默认的步长为1,range(3)表示的序列是[0,1,2]。range的遍历也很方便:
for i in range(3):
print i
c++11中增加了一项新特性range-based for循环,其实这也不是什么新东西,在c#、java和python等语言中已经有了。这种循环方式非常简洁,它的内部其实是对传统的begin()/end()方式的遍历做了包装,算是一个循环的语法糖。用法很简单:
//遍历vector
std::vector v;
for(auto i : v)
{
cout<
}
//以只读方式遍历map
std::map map;
for(const auto& item : map)
{
cout << item->first<second<
}
c++11的range-based for循环有意思的地方是他可以支持自定义类型的遍历,但是要求自定义类型满足三个条件:
要实现begin()和end(),他们分别用来返回第一个或最后一个元素的迭代器 www.jx-jf.com
提供迭代终止的方法;
提供遍历range的方法 www.yzyedu.com
满足这三个条件之后,我们自定义的类型就能支持range-based for循环了。
再回到刚才提到的python的range(),它很好用,但是c++中目前还没有类似的东西,虽然标准库中有很多容器如vector、list、queue、map、初始化列表和array等等都已经支持了range-based for循环,但是他们使用起来还是不够方便,比如要生成一个有序序列时,需要专门去初始化,如果有一个类似于python range的东西就比较完美了。虽然c++11现在没有,但我们可以自己用c++11去实现一个类似的range,而且我还想让这个range比python的range更强大,让它不仅仅能支持整数还能支持浮点数,同时还能双向迭代,实现这个range还是比较简单的,看看具体实现吧:
namespace Cosmos
{
template
class RangeImpl
{
class Iterator;
public:
RangeImpl(value_t begin, value_t end, value_t step = 1) :m_begin(begin), m_end(end), m_step(step)
{
if (step>0&&m_begin >= m_end)
throw std::logic_error("end must greater than begin.");
else if (step<0 && m_begin <= m_end)
throw std::logic_error("end must less than begin.");
m_step_end = (m_end - m_begin) / m_step;
if (m_begin + m_step_end*m_step != m_end)
{
m_step_end++;
}
}
Iterator begin()
{
return Iterator(0, *this);
}
Iterator end()
{
return Iterator(m_step_end, *this);
}
value_t operator[](int s)
{
return m_begin + s*m_step;
}
int size()
{
return m_step_end;
}
private:
value_t m_begin;
value_t m_end;
value_t m_step;
int m_step_end;
class Iterator
{
public:
Iterator(int start, RangeImpl& range) : m_current_step(start), m_range(range)
{
m_current_value = m_range.m_begin + m_current_step*m_range.m_step;
}
value_t operator*() { return m_current_value; }
const Iterator* operator++()
{
m_current_value += m_range.m_step;
m_current_step++;
return this;
}
bool operator==(const Iterator& other)
{
return m_current_step == other.m_current_step;
}
bool operator!=(const Iterator& other)
{
return m_current_step != other.m_current_step;
}
const Iterator* operator--()
{
m_current_value -= m_range.m_step;
m_current_step--;
return this;
}
private:
value_t m_current_value;
int m_current_step;
RangeImpl& m_range;
};
};
template
auto Range(T begin, T end, V stepsize)->RangeImpl
{
return RangeImpl(begin, end, stepsize);
}
template
RangeImpl Range(T begin, T end)
{
return RangeImpl(begin, end, 1);
}
template
RangeImpl Range(T end)
{
return RangeImpl(T(), end, 1);
}
}
再看看测试代码:
void TestRange()
{
cout << "Range(15):";
for (int i : Range(15)){
cout << " " << i;
}
cout << endl;
cout << "Range(2,6):";
for (int i : Range(2, 6)){
cout << " " << i;
}
cout << endl;
cout << "Range(10.5, 15.5):";
for (float i : Range(10.5, 15.5)){
cout << " " << i;
}
cout << endl;
cout << "Range(35,27,-1):";
for (int i : Range(35, 27, -1)){
cout << " " << i;
}
cout << endl;
cout << "Range(2,8,0.5):";
for (float i : Range(2, 8, 0.5)){
cout << " " << i;
}
cout << endl;
cout << "Range(8,7,-0.1):";
for (auto i : Range(8, 7, -0.1)){
cout << " " << i;
}
cout << endl;
cout << "Range('a', 'z'):";
for (auto i : Range('a', 'z'))
{
cout << " " << i;
}
cout << endl;
}
测试结果:
可以看到这个range不仅仅会根据步长生成有序序列,还能支持浮点类型和char类型以及双向迭代,比python的range更强大。
用c++11打造类似于python的range的更多相关文章
- (原创)用c++11打造类似于python的range
python中的range函数表示一个连续的有序序列,range使用起来很方便,因为在定义时就隐含了初始化过程,因为只需要给begin()和end()或者仅仅一个end(),就能表示一个连续的序列.还 ...
- python 中range numpy.arange 和 numpy.linspace 的区别
1.返回值不同 range返回一个range对象,numpy.arange和numpy.linspace返回一个数组. 2.np.arange的步长可以为小数,但range的步长只能是整数. 与Pyt ...
- python中range()函数的用法
python中range()函数可创建一个整数列表,一般用在for循环中. range()函数语法: range(start,stop[,step]) 参数说明: star: 计数从star开始.默认 ...
- python的range()函数使用方法
python的range()函数使用非常方便.它能返回一系列连续添加的整数,它的工作方式类似于分片.能够生成一个列表对象. range函数大多数时常出如今for循环中.在for循环中可做为索引使用.事 ...
- A Neural Network in 11 lines of Python
A Neural Network in 11 lines of Python A bare bones neural network implementation to describe the in ...
- 老司机带你用vagrant打造一站式python开发测试环境
前言 作为一个学习和使用Python的老司机,好像应该经常总结一点东西的,让新司机尽快上路,少走弯路,然后大家一起愉快的玩耍. 今天,咱们就使用vagrant配合xshell打造一站式Python ...
- Python的range()函数用法
Python的range()函数有三种用法,简单地说就是下图的三种用法: 运行结果如下:
- cplusplus 库 在线管理; 类似于 python的 pip install 、nodejs 的npm模块
cplusplus 库 在线管理: 类似于 python的 pip install .nodejs 的npm模块 还有 apache 经常使用的 Apache Ivy 项目依赖管理工具/Maven 这 ...
- # Pycharm打造高效Python IDE
Pycharm打造高效Python IDE 建议以scientific mode运行,在科学计算时,可以方便追踪变量变化,并且会提示函数的用法,比普通模式下的提示更加智能,一般在文件中引入了numpy ...
随机推荐
- 玩转12款Linux开源机器人
玩转12款Linux开源机器人 头条网2016-02-15 09:04 3DR Solo智能无人机发布于2015年中期.作为试图与大疆广受欢迎的Phantom系列无人机相抗衡的产品,它的双处理器运行L ...
- jQuery Builder
简介 作用:customize jQuery,可以仅包含自己想要的模块 jQuery Builder lets you easily build a custom version of jQuery ...
- HDU 4828 - Grids (Catalan数)
题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=4828 Catalan数的公式为 C[n+1] = C[n] * (4 * n + 2) / (n ...
- Java面向对象编辑
1.面向对象的软件开发方法简介: 1).把软件系统看成是各种对象的集合,更接近人类自然思维方式. 2).软件需求的变动往往都是功能的 ...
- 一不小心写了个bootstrap风格下拉控件 JqueryUI + bootstrap
受够了EasyUI的封闭,Bootstrap虽然华丽但是功能太渣,闲着无聊写个下拉控件玩玩吧,不喜勿喷哈... 第一步:先设计下我的下拉控件的样子 1.既然是bootstrap风格的,我想应该是这样的 ...
- JeeSite 企业信息管理系统基础框架
1. JeeSite概述 1.1. 简介 JeeSite是一个开源的企业信息管理系统基础框架.主要定位于“企业信息管理”领域,可用作企业信息管理类系统.网站后台管理类系统等.JeeSite是非常强调开 ...
- Android UI WebView的使用:
Android UI WebView的使用: /** * @author smiling * @date 2016/10 */ 布局: <?xml version="1.0" ...
- Hadoop HA的搭建
1.首先添加hosts文件 vim /etc/hosts 192.168.0.1 MSJTVL-DSJC-H01 192.168.0.2 MSJTVL-DSJC-H03 192.168.0.3 MSJ ...
- 使用exp&imp工具进行数据库备份及恢复
使用exp&imp工具进行数据库备份及恢复1.exp/imp使用方法介绍exp/imp为一种数据库备份恢复工具,也可以作为不同数据库之间传递数据的工具,两个数据库所在的操作系统可以不同.exp ...
- 【网络流#8】POJ 3469 Dual Core CPU 最小割【ISAP模板】 - 《挑战程序设计竞赛》例题
[题意]有n个程序,分别在两个内核中运行,程序i在内核A上运行代价为ai,在内核B上运行的代价为bi,现在有程序间数据交换,如果两个程序在同一核上运行,则不产生额外代价,在不同核上运行则产生Cij的额 ...