在迭代时从矢量中移除一个对象
我是C++的新手,所以我很难找出如何最好地从矢量中移除对象,同时仍然遍历它。在迭代时从矢量中移除一个对象
基本上,我需要遍历两个向量。对于每个项目,如果ID匹配,我可以删除它们。
//For every person, check to see if the available bags match:
for(std::vector<Person>::iterator pit = waitingPeopleVector.begin(); pit != waitingPeopleVector.end(); ++pit) {
for(std::vector<Bag>::iterator bit = waitingBagsVector.begin(); bit != waitingBagsVector.end(); ++bit) {
int pId = pit->getId();
int bId = bit->getId();
if(pId == bId){
//a match occurs, remove the bag and person
}
}
}
迭代器的工作是有点混乱,我知道我可以使用.erase()
功能上我的载体,但我真的不能传递pit
或bit
。任何帮助赞赏。谢谢
使用擦除删除语言将实现此目标,下面提供了使用lambdas和<algorithm>
函数(未经测试)的方法,用于从wPL
中删除与wBL
具有相同ID的元素。将这个扩展到这两个列表不应该太过努力。请注意,我们使用std::list
而不是std::vector
来加快删除。
std::list<Person> wPL;
std::list<Bag> wBL;
//...
wPL.erase(std::remove_if(wPL.begin(), wPL.end(),
[&wBL](auto x) { return std::find_if(wBL.begin(), wBL.end(), [](auto y)
{ return x.getId() == y.getId();); }), wPL.end() };
我怀疑一般情况下'std :: list'的移除速度要比'std :: vector'快。但是你可以肯定,如果你使用'std :: remove_if',它不会更快,因为它仍然需要移动值。这就是为什么有'std :: list :: remove_if',它在节点上工作。 –
@BenjaminLindley你说得很对,我猜上午2:20不是回答问题的时间 - 我会在明天编辑。 – ArchbishopOfBanterbury
这只会从'wPL'中删除而不''wBL' –
从标准:
迭代器从a.erase返回(Q)点到元件 立即q之前的元件被擦除之后。如果不存在这样的 元素,则返回a.end()。
我会用它像使用erase
方法:
std::vector<Person>::iterator pit = waitingPeopleVector.begin();
std::vector<Bag>::iterator bit = waitingBagsVector.begin();
while (pit != waitingPeopleVector.end())
{
bool didit;
while (bit != waitingBagsVector.end())
{
didit = false;
if (pit->getId() == bit->getId() && !didit)
{
bit = waitingBagsVector.erase(bit);
pit = waitingPeopleVector.erase(pit);
didit = true;
}
else
{
++bit;
}
}
if (didit)
continue;
else
++pit;
}
如果您得到一个匹配,可能会跳出内部循环。否则,你正在对'waitingPeopleVector.erase(pit)'返回的迭代器进行冗余检查。还要注意你的错字,等待**包** Vector.erase(坑)应该等待**人** Vector.erase(坑) –
正确!在代码中修复... – Mendes
'VECTOR'可能不是我们的最佳容器,因为从载体移除元素是昂贵的,有点尴尬。 – melpomene
相关:http://*.com/questions/6096279/keeping-a-valid-vectoriterator-after-erase –
另一个问题是你的方法是'O(n * n)'的复杂性。 100人,100袋,该循环进行10,000次迭代。是否有可能先排序id上的两个向量? – PaulMcKenzie