C++抽象编程——递归策略(3)——foreach语句的简单实现

我想,foreach循环大家都不会陌生,但凡熟悉一点高级的语言的人都是很熟悉的。它遍历每一个元素,并且对它进行处理,方便了很多。我第一次接触foreach的时候,是我在大一的时候学习的C#接触的。很可惜,在java跟C#中都有的这样的方便工具,但是C++是没有的(虽然在C++11中添加了for_each语句,详细用法看: C++抽象编程——STL实战(2)——查找与修改,但是我感觉用法上没那么方便)。本来我没打算写这个的,但是我下一篇的文章中要用到这个原理。所以这里我们先提一下foreach语句。

遍历与操作

通过遍历每一个元素并且能对它进行操作,是任何集合(STL)类的基本操作。此外,如果收集类的包装设计良好,客户端应该能够使用相同的策略来执行该操作,无论它们是循环遍历vector还是set中的所有元素,map中的所有key或value。标准模板库(STL)提供了一个强大的机制,称为迭代器,(迭代器的介绍:C++抽象编程——STL实战(1)——迭代器详解”)用于执行此操作。 不幸的是,理解这些标准迭代器取决于对C ++的低级细节的高度熟悉,最引人注目的是指针的概念。我们真正需要的一些方法是表达以下伪代码建议的算法思想:

For each element in a particular collection {
    Process that element
}

即遍历集合中的每一个元素,然后对其进行操作。

其他语言的foreach语法

我们现在来看看C#中的 foreach 语句的语法 :

foreach (type variable in collection) {
    body of the loop.
}

比如我这里有一个string类的set,即set< string > ss.有下面的代码:

foreach (string word in ss) {
    if (word.length() == 2) {
    cout << word << endl;
   }
}

这个操作的意思是,遍历ss集合,并将遍历的内容存储在word中,一旦发现集合中有长度等于2的单词,就将它输出。

迭代的顺序

当您使用foreach模式时,了解处理各个独立的值的顺序有时是有帮助。在这里没有特定的的规则。通常是基于效率的考虑。我们已经看到的类对于值的顺序有以下的特点:

  • 在处理一些类似与vector类的foreach时,过程类似与:
for (int i = 0; i < vec.size(); i++) {
    code to process vec[i]
}
  • 在处理二维的时候,foreach类似于:
for (int row = 0; row < grid.numRows(); row++) {
    for (int col = 0; col < grid.numCols(); col++) {
    code to process grid[row][col]
    }
}

行下标出现在外部循环中的这个顺序称为行主顺序(row-major order)。

  • 在处理STL的时候,foreach类似于
for (it = ss.begin(); it != ss.end(); it++){
    code to process cletion;
}

其中,it为迭代器。

C++中foreach的简单实现

我们既然知道了foreach的原理,那么能不能利用C++的强大去实现呢?我试了一下,很开心,我做到了。下面就说说过程吧。
先看我们上面的foreach语句:

set<string> ss;
foreach (string word in ss) { //遍历
    if (word.length() == 2) { //操作
    cout << word << endl;
   }
}

我们可以写成这样:

set<string> ss;
string word;  //因为set的类型为string类型
set<string>::iterator it; //创建迭代器
for (it = ss.begin(); it != ss.end(); it++){ // 遍历
        word = (*it); //将每一个元素存入对应的类型中,注意是这个集合中每一个独立的元素
        if (word.length() == 2) { //执行操作
        cout << word << endl;
     }
}

然后我们就可以根据这一个思路来写一个foreach函数了,比如这样的函数原型:

void foreach(string str, set<string> ss);

当然这只是设想而已,我就不写了,下面的生成排列数的连接就用实际的例子来证明这样的正确性:生成排列数

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值