如何使用满足某些条件的另一个向量的数据填充std :: vector

时间:2010-08-27 11:10:52

标签: c++ stl vector

我有一个点矢量,我需要得到距离小于给定点的值的那些。

我可以用一个简单的循环来做,但是有更好的方法吗?

提前致谢

5 个答案:

答案 0 :(得分:10)

使用std::remove_copy_if

#include <algorithm>
#include <vector>
#include <iostream>
#include <functional>
#include <iterator>

int main() {
    std::vector<int> v;
    v.push_back(3);
    v.push_back(2);
    v.push_back(6);
    v.push_back(10);
    v.push_back(5);
    v.push_back(2);
    std::vector<int> v2;

    std::remove_copy_if(v.begin(), v.end(), back_inserter(v2),
            std::bind2nd(std::greater<int>(),5));

    std::copy (v2.begin(), v2.end(), std::ostream_iterator<int>(std::cout));
    std::cout << std::endl;
    return 0;
}

remove_copy_if会将序列复制到每个未通过谓词的项的输出迭代器。在这种情况下,谓词是“x> 5”。对于通过谓词测试的每个项目,似乎没有等效copy_if,但您始终可以使用std::not1否定谓词。

答案 1 :(得分:4)

答案 2 :(得分:4)

正如Philip和Beta所暗示的那样,这是一种更通用的方法,使用仿函数谓词。 你可以使用C ++ 0x lambdas而不是handwriten仿函数。

#include <algorithm>
#include <vector>
#include <iostream>
#include <functional>
#include <iterator>

struct FunctorPredicate : public std::unary_function<bool,int>
{
   bool operator() (int i)
   {
      // do what you want here, in our case: test greater than 5.
      return i > 5; 
   }
}

int main() {
    std::vector<int> v;
    v.push_back(3);
    v.push_back(2);
    v.push_back(6);
    v.push_back(10);
    v.push_back(5);
    v.push_back(2);
    std::vector<int> v2;

    FunctorPredicate functorPredicate;
    std::remove_copy_if(v.begin(), v.end(), back_inserter(v2), functorPredicate);

    std::copy (v2.begin(), v2.end(), std::ostream_iterator<int>(std::cout));
    std::cout << std::endl;
    return 0;
}

继承表单std :: unary_function定义了以下两个typedef: int的argument_type和bool的result_type。

在{+ 3}}的Cplusplus STL参考中,还有另一个更简单std::function<bool (int)>的例子。

答案 3 :(得分:2)

塞巴斯蒂安已经提出了boost::make_xxx_range功能,但我建议更进一步。仅使用boost :: make_xxx_range非常麻烦。通常,您希望使用boost :: range;)

#include <vector>
#include <iostream>
#include <boost/lambda/lambda.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/range/adaptor/filtered.hpp>

using namespace boost::adaptors;
using namespace boost::lambda;

int main()
{
    std::vector<int> v = {3, 2, 6, 10, 5, 2};
    std::vector<int> v2;
    int dist = 5;

    boost::push_back(v2, filter(v, _1 > dist));

    boost::copy(v2, std::ostream_iterator<int>(std::cout, ","));
    std::cout << std::endl;
    return 0;
}

答案 4 :(得分:0)

Maxim已经提出了boost::filter_iterator,但我建议更进一步。单独使用增强迭代器非常麻烦。通常,您希望过滤范围,复制范围或搜索范围。对于每个boost迭代器,我们都有一个实用函数make_xxx_range,如下所示:

#include <boost/iterator/filter_iterator.hpp>
#include <boost/range/iterator_range.hpp>

template< class Range, class Pred >
boost::iterator_range< boost::filter_iterator< Pred, typename boost::range_iterator<Range>::type > > 
make_filter_range( Range& rng, Pred p ) {
    return boost::make_iterator_range( boost::make_filter_iterator(pred, boost::begin(rng), boost::end(rng)), boost::make_filter_iterator(pred, boost::end(rng), boost::end(rng)) );
}

有了这个,你的问题的解决方案是微不足道的:

#include <boost/lambda/lambda.hpp> 
int main() {
    std::vector<int> v;
    // fill vector
    std::vector<int> v2 = boost::copy_range< std::vector<int> >( 
        make_filter_range( v, boost::lambda::_1 > 5 );
}