Как удалить все четные целые числа из набора <int>в C ++ - PullRequest
10 голосов
/ 18 января 2010

Я новичок в 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 увеличивается после того, как он удален. значит ли это, что Итр должен указывать на начало набора каждый раз после того, как я удаляю элемент из набора?

Ответы [ 4 ]

16 голосов
/ 18 января 2010
 for(set<int>::iterator itr = s.begin(); itr != s.end(); ){
  if (!(*itr % 2))
      s.erase(itr++);

  else ++itr;
 }

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

11 голосов
/ 18 января 2010

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

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

8 голосов
/ 18 января 2010

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

for(set<int>::iterator itr = s.begin(); itr != s.end();)
{
    set<int>::iterator here = itr++;
    if (!(*here % 2))
        s.erase(here);
}
0 голосов
/ 19 января 2010

Лучший способ - использовать комбинацию 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: хотя мое решение неверно, я не удаляю его. Это может быть хорошим уроком для тех, кто, как я, не занимается изменяемыми / неизменяемыми итераторами

...