2017-01-28 20 views
0

Когда я попробовал эту часть кода:Ошибка в C++ Set?

int x=*(s.rbegin()); 
while(!s.empty()&&0<x) 
{ 
    s.erase(x); 
    x=*(s.rbegin()); 
} 

Он работает в бесконечном цикле, потому что на самом деле не стирать ничего, когда я называю стереть. Это кажется странным, потому что * (s.rbegin()) обязательно должен находиться в s.

+1

Какова ценность x? –

+4

У вас есть неопределенное поведение после того, как последнее значение набора будет удалено, а затем вы отделите от него итератор. Если вы не можете гарантировать, что условие '0

+0

Как вы заявляете '' '? –

ответ

-1

Вы должны проверить в конце набора, перед x=*(s.rbegin());

int x=*(s.rbegin()); 
while(!s.empty() && 0<x) 
{ 
    s.erase(x); 
    if(!s.empty()) 
     x=*(s.rbegin()); 
} 
+0

"* проверить конец набора *" - это относится к первому 'rbegin()', а также перед входом в цикл, а не только 'rbegin()' внутри цикла. –

0

Изменить порядок действий, вы удалите элемент, который вы хотели получить .. например:

std::set<int> s; 

int x; 
s.insert(5); 
s.insert(15); 
s.insert(25); 
s.insert(0); 
s.insert(20); 
while(!s.empty()&& (0<(x=*s.rbegin()))) 
{ 
    std::cout<< x << "\n"; 
    s.erase(x); 
} 

Имейте в виду, что в пути вы определили время. Вывод кода выше

25 
20 
15 
5 

Имейте в виду, что в пути вы определили в то время как() цикл вы намеревались остановить, если он находит 0 элемент. После выхода осталось 0, набор не будет пустым. Традиционно используется итерация выглядит

for (auto it=s.rbegin(); it!=s.rend(); ++it) 
{ 
} 
0

Попробуйте вместо этого:

if (!s.empty()) 
{ 
    int x = *(s.rbegin()); 
    while (0 < x) 
    { 
     s.erase(x); 
     if (s.empty()) break; 
     x = *(s.rbegin()); 
    } 
} 

Кроме того, попробуйте стереть с помощью итераторов вместо значений:

std::set<int>::reverse_iterator iter = s.rbegin(); 
while ((iter != s.rend()) && ((0 < *iter)) 
    s.erase((iter++).base()); 
+0

std :: remove_if не будет работать с std :: set, вы получите назначение ошибки местоположения только для чтения. Последний компилятор, который мог бы сделать то, что я знаю, был vc6 (из-за некоторых необычных реализаций STL) – Swift

+0

@Swift спасибо, я удалил эту часть из моего ответ. –

0

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

s.erase(s.upper_bound(0),s.end()); 

upper_bound дает вам итератор на первое число больше 0. Так как все элементы из этого одного до конца гарантированно быть больше нуля, вы можете стереть их всех.