2013-09-17 3 views
1

Эта программа запрашивает у пользователя число, а затем сохраняет все номера до и включает их в контейнер. Проблема в том, что я удаляю определенные числа, но не могу, потому что программа зависает всякий раз, когда я пытаюсь стереть нечетное число (обозначается NUMBER ниже). Он отлично работает, когда я стираю даже цифры. Однако я заметил, что если я изменил начальное значение y на четное число, я не смогу стереть четные числа. Здесь у меня он установлен на нечетное число. Что я сделал не так?Контейнер с набором C++ не может стереть нечетные числа

#include <iostream> 
#include <set> 
using namespace std; 

int main() 
{ 
set<int>s; 
set<int>::iterator cnt; 
int n,x,y=1; 
cout<<"Number: "; 
cin>>n; 
for(x=0;x<n-1;x++) 
{ 
    s.insert(y); 
    y++; 
} 
for(cnt=s.begin();cnt!=s.end();cnt++) 
{ 
    if(*cnt==NUMBER) 
    s.erase(cnt); 
} 
for(cnt=s.begin();cnt!=s.end();cnt++) 
cout<<*cnt<<"\n"; 
return 0; 
} 
+0

Ugh - это C++ не C, пожалуйста, поместите ваши объявления переменных вблизи их использования, или сделать это: 'ЬурейеГо набор Инд.Сброса; MySet s;/* ... */for (MySet :: iterator cnt = s.begin(); cnt! = s.end(); ++ cnt) ' – kfsone

ответ

2

Документация set::erase говорит «итераторы, указатели и ссылки, относящиеся к элементам удалены с помощью функции аннулируются. Все остальные итераторы, указатели и ссылки сохраняют свою юридическую силу.» не

for(cnt=s.begin();cnt!=s.end();cnt++) 
{ 
    if(*cnt==NUMBER) 
    s.erase(cnt); 
} 

Как только вы s.erase(cnt), cnt больше не относится к элементу множества. Поэтому, когда вы делаете cnt++, вы пытаетесь указать его на «следующий элемент», но нет следующего элемента.

Одно из возможных решений:

cnt = s.begin(); 
while (cnt != s.end()) 
{ 
    if (*cnt == NUMBER) 
     s.erase(cnt++); 
    else 
     ++cnt; 
} 
1

std::set имеет erase, который принимает значение ключа вместо итератора, чтобы процесс удаления всего ваш может быть сведен к: s.erase(NUMBER);.

Вы также можете использовать std::copy, чтобы получить данные из набора для вывода, так что вы в конечном итоге с:

s.erase(NUMBER); 
std::copy(s.begin(), s.end(), 
      ostream_iterator<int>(cout, "\n")); 

В качестве альтернативы, вы можете отфильтровать нежелательное значение при копировании выхода из набора в стандартный вывод, что-то вроде:

std::remove_copy(s.begin(), s.end(), 
       ostream_iterator<int>(cout, "\n"), NUMBER); 
Смежные вопросы