STL:写“哪里"向量的运算符 [英] STL: writing "where" operator for a vector
问题描述
我需要根据几个布尔谓词在向量中找到索引.
例如:
vectorv;向量idx;idx=where( bool_func1(v), bool_func2(v), ... );
声明**where**
函数的方法是什么,以便在向量上使用几个用户定义的布尔函数?
谢谢阿尔曼.
一周后编辑
我用模板做了一些复杂的解决方案.但实际上,我可以将已经预定义的 valarray
用于我的任务.这是代码片段,也许您会发现它很有用:
double dr=Rc/(double)Nbins, r;sigma.resize(Nbins);rr=西格玛;valarrayvz(&data.vz[0], data.vz.size());double mvel=vz.sum()/(double)vz.size();for(size_t i=0l;i<Nbins;i++){r=dr*i;valarrayids = (dist < r+dr) &&(dist > r);//神奇的valarray;如果(ids.max()){valarrayd=vz[ids];//我们可以使用间接操作.d-=mvel;d=pow(d,2.0);sigma[i]= sqrt(d.sum()/(double)d.size());rr[i]=r;cout<
让你的 bool_xxx 函数实际上是一种特定类型的函子(标签调度就足够了).然后覆盖 ||和&&对于它们,这些运算符返回 bool_and 或 bool_or.然后你可以像这样使用你的 bool_ 谓词:
<预><代码>std::find_if(vect.begin(), vect.end(), bool_x1() || bool_x2() && (bool_x3() || bool_x4() && bool_x5()));如果您想编写一个where"函数,那么您显然想用一组不同的 bool_xxx 函数多次执行此操作.即使你知道你现在想要某种类型的构图,你也可以让它尽可能通用.这就是我要做的.
基于此评论:@Jerry:例如我需要知道: id=where(v <10.0 && v>1.0);稍后我想知道: id=where(v < fun(v)); 使用 boost::lambda 可能会更好:
<预><代码>命名空间 l = boost::lambda;std::find_if(vect.begin(), vect.end(), l::_1 <10.0 && l::_1 > 1.0);std::find_if(vect.begin(), vect.end(), l::_1 < l::bind(fun, l::_1));或者,如果你讨厌 lambda 或者不允许使用它......或者只是想要一个稍微好一点的语法(但不能直接使用函数)那么只需创建你自己的占位符类型并覆盖它以返回 bool_xxx 函子运算符 <、> 等...
Edit2:这是一个未经测试的地方,它向所有匹配的对象返回一个迭代器向量:
<预><代码>模板它是递归的,在某些实现上可能会很慢,但有一种方法可以做到.
I need to find the indexes in the vector based on several boolean predicates.
ex:
vector<float> v;
vector<int> idx;
idx=where( bool_func1(v), bool_func2(v), ... );
What is the way to declare **where**
function, in order to use the several user defined boolean functions over the vector?
thanks Arman.
Edit after one week
I did some complex solutions with templates. But in reality one can use already predefined valarray
for my tasks. Here is the code snippet maybe one can find it useful:
double dr=Rc/(double)Nbins, r;
sigma.resize(Nbins);
rr=sigma;
valarray<double> vz(&data.vz[0], data.vz.size());
double mvel=vz.sum()/(double)vz.size();
for(size_t i=0l;i<Nbins;i++)
{
r=dr*i;
valarray<bool> ids = (dist < r+dr) && (dist > r);//The magic valarray<bool>
if(ids.max())
{
valarray<double> d=vz[ids];//we can use indirect operation.
d-=mvel;
d=pow(d,2.0);
sigma[i]= sqrt(d.sum()/(double)d.size());
rr[i]=r;
cout<<i<<") "<<r<<" "<<sigma[i]<<endl;
}
}
Make your bool_xxx functions actually functors of a specific kind of type (tag dispatching would be enough). Then override || and && for them such that these operators return a bool_and, or bool_or. Then you can use your bool_ predicates like so:
std::find_if(vect.begin(), vect.end(), bool_x1() || bool_x2() && (bool_x3() || bool_x4() && bool_x5()));
If you're tempted to write a "where" function then you apparently want to do this more than once with a different set of bool_xxx functions. Even if you know that you want a certain type of composition now, you may as well make it as universal as possible. This is how I'd do it.
Edit:
Based on this comment: @Jerry: For example I need to know: id=where(v < 10.0 && v>1.0); and somewhere later I would like to know: id=where(v < fun(v)); you may be better off with boost::lambda:
namespace l = boost::lambda;
std::find_if(vect.begin(), vect.end(), l::_1 < 10.0 && l::_1 > 1.0);
std::find_if(vect.begin(), vect.end(), l::_1 < l::bind(fun, l::_1));
Or, if you hate lambda or aren't allowed to use it...or just want a very slightly nicer syntax (but inability to use functions directly) then just make your own placeholder type and override it to return bool_xxx functors on operators <, >, etc...
Edit2: Here's an untested where that returns a vector of iterators to all objects matching:
template < typename ForwardIter, typename Predicate >
std::vector<ForwardIter> where(ForwardIter beg, ForwardIter end, Predicate pred)
{
ForwardIter fit = std::find_if(beg,end,pred);
if (fit == end) return std::vector<ForwardIter>();
ForwardIter nit = fit; ++nit;
std::vector<ForwardIter> collection = where(nit,end,pred);
collection.push_front(fit);
return collection;
}
It's recursive and could be slow on some implementations but there's one way to do it.
这篇关于STL:写“哪里"向量的运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!