我有一个点矢量,我需要得到距离小于给定点的值的那些。
我可以用一个简单的循环来做,但是有更好的方法吗?
提前致谢
答案 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)
#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 );
}