如何擦除矢量中的最后和/或唯一元素
How to erase last and/or unique element in a vector?
我需要根据它们的值从向量中擦除元素,我尝试了习语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);
但是当jets_pt
的大小为1时,我得到一个segmentation violation
。整个程序获取实验的数据并循环,map记录事件的名称和我需要的相关变量,而vector存储map的字符串和我需要记录的值。我想从向量中删除那些不满足几个条件的值
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);
这听起来像是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() );
我假设在您的实际代码中,您实际上在循环的某个地方为迭代器调用operator++
。但是,仍然存在erase会使迭代器失效的问题,因此需要执行
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,...
,由[&]
表示),这些变量可用于remove_if
。auto
意味着编译器应该推断变量的类型(因为我们没有编译器为这个lambda生成的类型的名称)。
尝试以下操作(近似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返回的迭代器中擦除vector对象的末尾。您可以根据需要编辑谓词remove_if。
在迭代时不要擦除条目!
相关文章:
- lower_bound()返回最后一个元素
- 从控制台中删除最后打印的元素
- 使用运算符 [] 引用 std::vector 上最后一个元素时出现问题<>
- Lower_bound不适用于具有 3 个元素的向量的最后一个元素
- 查找数组中第一个最小值和最后一个最大值元素之间的算术平均值
- 仅显示链表的最后一个元素
- 删除列表 c++ 中的最后 3 个元素
- push_back通过自行创建的对象获取最后一个元素的向量
- 使用 map.end() 访问 map 的最后一个元素
- 如何知道地图中的最后一个元素是否被删除?
- std::矢量保存 只推送最后一个元素
- 反转后不返回最后一个元素
- 经过最后一个数组元素末尾的指针是否应该等于超过整个数组末尾的指针?
- 如何在新数组较小时创建新数组并将旧数组的最后一个元素复制到新数组中?
- 在 QListView 中显示最后一个元素
- list.push_back似乎复制了最后添加的元素
- C++:在进行切片时对迭代器的约定,特别是对于访问最后一个元素并最终将其删除
- 遍历列表包含排除最后一个元素的内容
- 如何打印第一个和最后一个元素的和,然后打印第二个和倒数第二个元素的总和,依此类推
- C++链表最后一个元素的迭代器?