как удалить все четные целые числа из набора в c++

Я новичок в C++. Я хотел бы знать, как опытные программисты делают это.

что у меня есть:

set<int> s;
s.insert(1);
s.insert(2);
s.insert(3);
s.insert(4);
s.insert(5);

for(set<int>::iterator itr = s.begin(); itr != s.end(); ++itr){
if (!(*itr % 2))
    s.erase(itr);
}

и, конечно, это не работает. потому что itr увеличивается после его удаления. означает ли это, что Itr должен указывать на начало набора каждый раз после удаления элемента из набора?

4 ответов


 for(set<int>::iterator itr = s.begin(); itr != s.end(); ){
  if (!(*itr % 2))
      s.erase(itr++);

  else ++itr;
 }

эффективный STL Скоттом Майерсом


удаление элемента из std:: set только делает недействительными итераторы, указывающие на этот элемент.

перед удалением целевого элемента получите итератор к следующему элементу.


вам не нужно возвращаться к началу. set::erase только аннулирует итераторы, которые ссылаются на стираемый элемент, поэтому вам просто нужно скопировать итератор и увеличить перед стиранием:

for(set<int>::iterator itr = s.begin(); itr != s.end();)
{
    set<int>::iterator here = itr++;
    if (!(*here % 2))
        s.erase(here);
}

лучший способ-использовать комбинацию remove_if и erase

s.erase(remove_if(s.begin(), s.end(), evenOddFunctor), s.end())

это будет полезно http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Erase-Remove

Также см. эффективный STL Скоттом Мейерсом

Edit: хотя мое решение неверно, я не удаляю его. Это может быть хорошее обучение для кого-то вроде меня, кто не о изменяемых/неизменяемых итераторах