变换 - 变异序列算法

时间:2015-03-30 09:06:41

标签: c++ algorithm stl transform

我知道C ++中的transform算法是mutating sequence algorithm。但我从未见过有人使用transform来改变序列。每当我在互联网上搜索示例代码时,我得到的变换算法类似于for_each算法。

请提供一个链接或示例,以便我了解mutating sequence性质。

编辑:当我通过This SO question.时,我变得更加困惑 它说for_eachnon-modifying sequence算法。所以我可以修改for_each的元素而不是容器的结构。提供的答案不正确。如果for_each也可以修改该元素,我们可以将for_each替换为transform,并且不需要for_each算法,除非它的实现可能很简单。

2 个答案:

答案 0 :(得分:4)

变异序列算法意味着算法将改变(修改)它所使用的容器。在下面的示例中,类型为foo的容器std::vector已被修改。

std::string s("hello");
std::vector<int> foo;
std::transform(s.begin(), s.end(), back_inserter(foo), ::toupper);
std::cout << std::string(foo.begin(), foo.end());

output是“HELLO”

std::for_each

无法做到这一点

是的,提供的答案对我来说是正确的。另请查看C ++中的Nonmodifying Sequence AlgorithmsMutating Sequence Algorithms列表以验证您的断言。

答案 1 :(得分:2)

这是一个简单的例子

#include <iostream>
#include <algorithm>
#include <iterator>

int main() 
{
    int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    for ( int x : a ) std::cout << x << ' ';
    std::cout << std::endl;

    std::transform( std::begin( a ), std::end( a ), std::begin( a ),
                    []( int x ) { return x * x; } );

    for ( int x : a ) std::cout << x << ' ';
    std::cout << std::endl;

    return 0;
}

输出

1 2 3 4 5 6 7 8 9 10 
1 4 9 16 25 36 49 64 81 100 

使用算法std::for_each

可以做到同样的事情
#include <iostream>
#include <algorithm>
#include <iterator>

int main() 
{
    int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    for ( int x : a ) std::cout << x << ' ';
    std::cout << std::endl;

    std::for_each( std::begin( a ), std::end( a ),
                   []( int &x ) { x = x * x; } );

    for ( int x : a ) std::cout << x << ' ';
    std::cout << std::endl;

    return 0;
}

尽管std::for_each在其描述中被称为非可变算法,但仍有书面

  

2效果:将f应用于取消引用每个迭代器的结果   范围[第一个,最后一个],从第一个开始到最后一个 -   1. [注意:如果第一类满足可变迭代器的要求,则f可以通过以下方式应用非常数函数:   解除引用的迭代器 .-结束注释]

因此实际上它可以用作可变算法。

两种算法std::for_eachstd::transform都属于非修改序列操作的类别,因为它们不会更改源序列元素的顺序。

似乎你混合了两个概念:可变算法和非修改序列算法。:)