使用C ++ 11 lambdas对std :: vector元素进行成对比较

时间:2015-04-07 01:43:35

标签: c++11

我很喜欢C ++ 11,并尝试采用更优雅的方式对两个std::vector<double>进行成对比较。对于成对最大值,我使用相当不优雅的

typedef std::vector<double> vec;
vec pairwiseMax(vec& a, vec& b)
{
    ASSERT(a.size() == b.size());
    vec c(a); // seed with a
    for (unsigned int i = 0; i < a.size(); i++)
    {
        if (b[i] > a[i]) // bigger than
            c[i] = b[i];
    }
    return c;
}

然而,使用lambdas和std::for_each似乎更好,如下所示,它提取std::vector<double>的绝对最大值,但我没有想出任何东西。

inline double vecabs(vec v)
{
    if (v.empty()) return 0.0;
    vec::iterator it = 
        std::max_element(v.begin(), v.end(), 
        // Start lambda function
        [](double const& a, double const& b)
        {
            return (std::abs(a) < std::abs(b));
        });
    return *it;
};

在伊戈尔的帖子之后,我现在有了:

vec c;
c.reserve(a.size());
std::transform(a.begin(), a.end(), b.begin(),
    std::back_inserter(c),
    [](double const& d, double const& e)
    { return max(d, e); });

两个问题:

  1. 为什么不像以前一样将vec a复制到vec c
  2. 是不是在使用back_inserter添加了很多额外的操作?如果开始c==a,则需要更少的c插入。
  3. 像这样:

    vec c(a); // seed with a
    std::transform(a.begin(), a.end(), b.begin(),
        c.begin(),
        [](double const& d, double const& e)
        { return max(d, e); });
    return c;
    

2 个答案:

答案 0 :(得分:3)

vec c;
c.reserve(a.size());
std::transform(a.begin(), a.end(), b.begin(),
               std::back_inserter(c),
               std::max<double>);

答案 1 :(得分:1)

Igor的解决方案很棒,但我在编译时遇到了麻烦。我发现我需要在匿名函数中包装std :: max以使其编译。

这里有两个模板函数,它们允许对任意数量的向量采用成对最大值:

// pairwise maximum                                               
template<typename T>                                              
vector<T> pmax(const std::vector<T>& a, const std::vector<T>& b) {
    std::vector<T> c;                                             
    assert(a.size() == b.size());                                 
    c.reserve(a.size());                                          
    std::transform(a.begin(), a.end(), b.begin(),                 
                   std::back_inserter(c),                         
                   [](T a, T b) { return std::max<T>(a, b); });   
    return c;                                                     
}                                                                 

// maximum of all vectors
template<typename T>                                                      
vector<T> vpmax(const std::vector<std::vector<T>>& vv) {                  
    std::vector<T> c;                                                     
    if (vv.empty()) return c;                                             
    c = vv.front();                                                       
    typename std::vector<std::vector<T> >::const_iterator v = vv.begin(); 
    ++v; // skip the first element                                        
    for ( ; v != vv.end(); ++v) {                                         
        c = pmax(c, *v);                                                  
    }                                                                     
    return c;                                                             
}