STL通用算法: for_each,c++11标准范围for,transform.

之前的算法都用到了for_each算法把容器内的元素输出到屏幕上,所以今天讲讲for_each这个算法,还有和它功能类似的范围for的用法.

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

template <typename T>
class Print
{
public:
    void operator()(T a)
    {
        cout << a << " ";
    }
};

int main()
{
    vector<int> s = {1,2,5,7,4,6,9};

    for_each(s.begin(), s.end(), Print<int>());//输出1 2 5 7 4 6 9
    cout << endl;

    system("pause");
    return 0;
}

看完上面非常简单的代码后,可能就会有小伙伴会问了,既然可以用for_each来代替我们手写的for循环来输出容器内的元素,那么是否可以用for_each这个算法来给容器内的值进行一些操作呢,那当然是可以的啊,下面看实现的代码:

template <typename T>
class Print
{
public:
    //只要在这里加个引用就可以实现了,因为a作为形参作为左操作数,而容器内的元素则作为右操作数,a相当于是容器内元素的别名,所以当然可以进行值的操作呗.
    void operator()(T &a)
    {
        a++;
        cout << a << " ";
    }
};

for_each手动实现:在STL源码剖析中,SGI版本里for_each是有返回值的,但是此返回值无用,所以这里就不放返回值了.

template <typename T, typename C>
void myFor_each(T &first, T &last, C function)
{
    while (first != last)
    {
        function(*first);
        first++;
    }
}

在C++11标准中,多了一个范围for的用法,接下来我们来看看:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

template <typename T>
class Print
{
public:
    void operator()(T a)
    {
        cout << a << " ";
    }
};


int main()
{
    vector<int> s = {1,2,5,7,4,6,9};

    //和我们以前使用的for循环不太一样,用temp临时变量作为容器s内一个元素的别名,然后进行操作,当然可以改变值啦!
    for (auto &temp : s)
    {
        temp += 1;
        cout << temp << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

从在原容器元素的基础上修改元素的功能来看,transform同样能实现相同的功能.

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

template <typename T>
class Print
{
public:
    void operator()(T a)
    {
        cout << a << " ";
    }
};

template <typename T>
class myPlus
{
public:
    int operator()(T a)
    {
        return a + 5;
    }
};


int main()
{
    vector<int> s = { 1, 2, 5, 7, 4, 6, 9 };

    //transform算法用来产生一个新序列,然后把新序列赋值给一个容器.此例是直接覆盖原容器的元素.
    //给每一个元素+5,然后从s.begin()这个迭代器开始赋值.当然别的容器也可以~不过容器内的元素数量必须要超过容器s,否则会报错.
    transform(s.begin(), s.end(), s.begin(), myPlus<int>());
    for_each(s.begin(),s.end(),Print<int>());
    cout << endl;

    system("pause");
    return 0;
}

这里是transform的实现.注意返回值是新序列中最后一个元素的后一个元素,等同于s.end().

template <typename T, typename C>
T myTransform(T first, T last, T new_first, C function)
{
    while (first != last)
    {
        *new_first++ = function(*first++);
    }
    return new_first;
}

transform还有一个重载用法,是用两个序列产生一个新序列.

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

template <typename T>
class Print
{
public:
    void operator()(T a)
    {
        cout << a << " ";
    }
};

template <typename T>
class myPlus
{
public:
    int operator()(T a, T b)
    {
        return a + b;
    }
};


int main()
{
    vector<int> s = { 1, 2, 5, 7, 4, 6, 9 };
    vector<int> temp(s.size(),10);

    //把两个序列的所有值全部相加,产生的新序列赋值给了容器s.
    //注意,第二个序列的元素必须要大于等于第一个序列的元素,否则会报错.
    transform(s.begin(), s.end(), temp.begin(),s.begin(), myPlus<int>());
    for_each(s.begin(), s.end(), Print<int>());
    cout << endl;

    system("pause");
    return 0;
}
template <typename T, typename C>
T myTransform(T first, T last, T first_2, T new_first, C function)
{
    while (first != last)
    {
        *new_first++ = function(*first++,*first_2++);
    }
    return new_first;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值