在迭代时从矢量中移除一个对象

问题描述:

我是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()功能上我的载体,但我真的不能传递pitbit。任何帮助赞赏。谢谢

+0

'VECTOR'可能不是我们的最佳容器,因为从载体移除元素是昂贵的,有点尴尬。 – melpomene

+0

相关:http://*.com/questions/6096279/keeping-a-valid-vectoriterator-after-erase –

+0

另一个问题是你的方法是'O(n * n)'的复杂性。 100人,100袋,该循环进行10,000次迭代。是否有可能先排序id上的两个向量? – PaulMcKenzie

使用擦除删除语言将实现此目标,下面提供了使用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() }; 
+0

我怀疑一般情况下'std :: list'的移除速度要比'std :: vector'快。但是你可以肯定,如果你使用'std :: remove_if',它不会更快,因为它仍然需要移动值。这就是为什么有'std :: list :: remove_if',它在节点上工作。 –

+0

@BenjaminLindley你说得很对,我猜上午2:20不是回答问题的时间 - 我会在明天编辑。 – ArchbishopOfBanterbury

+0

这只会从'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; 
} 
+1

如果您得到一个匹配,可能会跳出内部循环。否则,你正在对'waitingPeopleVector.erase(pit)'返回的迭代器进行冗余检查。还要注意你的错字,等待**包** Vector.erase(坑)应该等待**人** Vector.erase(坑) –

+0

正确!在代码中修复... – Mendes