我需要根据它们的值从矢量中删除元素,我已经尝试了成语erase-remove_if但是要擦除项目的条件并不那么简单,我尝试了类似
的内容map<string, TLorentzVector> map_jets
vector<pair<string,double> > jets_pt
for( vector<pair<string,double> >::iterator it1 = jets_pt.begin(); it1 != jets_pt.end(); ){
if( fabs(map_jets[it1->first].PseudoRapidity()) > 2.5 )
jets_pt.erase(it1);
但是当segmentation violation
的尺寸= 1时我得到jets_pt
。
整个程序获取实验数据并循环,地图跟踪事件的名称和我需要的相关变量,而向量存储地图的字符串和我需要跟踪的值。
我想从向量中删除那些满足一些条件的值
if( fabs(map_jets[it1->first].PseudoRapidity()) > 2.5 )
jets_pt.erase(it1);
if( map_jets[it->first].DeltaR(map_leps["lep1"]) < 0.4 && map_jets[it->first].DeltaR(map_leps["lep2"]) < 0.4 && map_jets[it->first].DeltaR(map_leps["lep3"]) )
jets_pt.erase(it);
if( jets_emfr[k] > 0.9 )
jets_pt.erase(it);
答案 0 :(得分:2)
这听起来像std::remove_if
算法的工作,可用于从容器中删除与给定谓词匹配的元素。
这样的事情应该有效:
bool myPredicate( pair<string, double> element ) {
return fabs(map_jets[elem.first].PseudoRapidity()) > 2.5
|| (map_jets[elem.first].DeltaR(map_leps["lep1"]) < 0.4 && ... )
|| ...
}
jets_pt.erase( remove_if( jets_pt.begin(), jets_pt.end(), myPredicate ),
jets_pt.end() );
答案 1 :(得分:1)
我假设您在实际代码中实际上为循环中的某个地方的迭代器调用operator++
。但是,您仍然遇到擦除使迭代器无效的问题,因此您需要执行
it = jets_pt.erase(it1);
然而,remove_if - erase
在这里确实是一个更合适的解决方案
我应该重新推荐以下内容:
struct remove_functor
{
map<string, TLorentzVector>& map_jets;
map<...>& map_leps;
remove_functor(map<string, TLorentzVector>& m_jets, map<...>& m_leps): map_jets(m_jets), map_leps(m_leps)
{}
bool operator()(const pair<string,double>& p)
{
return (fabs(map_jets[p.first].PseudoRapidity()) > 2.5)
|| ((map_jets[p.first].DeltaR(map_leps["lep1"]) < 0.4)
&& (map_jets[p.first].DeltaR(map_leps["lep2"]) < 0.4)
&& (map_jets[p.first].DeltaR(map_leps["lep3"]));
}
}
然后你可以简单地使用
jets_pt.erase(remove_if(jets_pt.begin(), jets_pt.end(), remove_functor(map_jets, map_leps)), jets_pt.end());
当然在c ++ 0x中你可以简单地使用lambda函数:
auto predicate = [&](const pair<string, double>& p) {bool operator()(const pair<string,double>& p)
{
return (fabs(map_jets[p.first].PseudoRapidity()) > 2.5)
|| ((map_jets[p.first].DeltaR(map_leps["lep1"]) < 0.4)
&& (map_jets[p.first].DeltaR(map_leps["lep2"]) < 0.4)
&& (map_jets[p.first].DeltaR(map_leps["lep3"]));
};
jets_pt.erase(remove_if(jets_pt.begin(), jets_pt.end(), predicate), jets_pt.end());
predicate = [&](...){...};
创建一个仿函数(通过lambda语法),它通过引用捕获所有使用的变量(map_jets, map_leps,...
,由[&]
表示),可用于{ {1}}。 remove_if
表示编译器应该推断变量的类型(因为我们没有编译器为这个lambda生成的类型的名称)。
答案 2 :(得分:1)
尝试以下操作(近似c ++ 11,我无权访问此计算机上符合c ++ 11的编译器):
jets_pt.erase(
remove_if(
jets_pt.begin(),
jets_pt.end(),
[&](const pair<string,double> &p) {
return fabs(map_jets[p.first].PseudoRapidity()) > 2.5;
}),
jets_pt.end());
基本上,你想从remove_if返回的迭代器中删除直到向量的末尾。您可以根据需要将谓词编辑为remove_if。
答案 3 :(得分:0)
迭代时不要删除条目!您使循环约束无效。