0

When I tried this part of the code:

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

It runs into an infinite loop because it doesn't actually erase anything when I call erase. This seems weird because *(s.rbegin()) should definitely be in s.

m_callens
  • 6,100
  • 8
  • 32
  • 54

4 Answers4

0

Change order of actions, you delete element you wanted to get.. for example:

 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);
 }

Be aware that in way you defined while. Output of code above will be

25
20
15
5

Be aware that in way you defined while() loop you intended to stop if it finds 0 element. There is 0 left after the exit, set will not be empty. Traditionally used iteration looks like

for (auto it=s.rbegin(); it!=s.rend(); ++it)
{
}
Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42
0

Try this instead:

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

Alternatively, try erasing using iterators instead of values:

std::set<int>::reverse_iterator iter = s.rbegin();
while ((iter != s.rend()) && ((0 < *iter))
    s.erase((iter++).base());
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • std::remove_if will not work with std::set, you'll get assignment of read-only location error. last compiler that could do that of which I know was vc6 (due to some unusual implementations of STL) – Swift - Friday Pie Jan 28 '17 at 04:20
0

It seems that you are trying to erase all elements in the set which are positive. This can be done much simpler with this single line:

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

upper_bound gives you the iterator to the first number greater than 0. Since all elements from this one to the end are guaranteed to be greater than zero, you can erase them all.

Raziman T V
  • 480
  • 1
  • 4
  • 12
-1

You should check for the end of set before x=*(s.rbegin());

int x=*(s.rbegin());
while(!s.empty() && 0<x)
{
    s.erase(x);
    if(!s.empty())
        x=*(s.rbegin());
}
cpatricio
  • 457
  • 1
  • 5
  • 11
  • "*check for the end of set*" - that applies to the first `rbegin()` as well before entering the loop, not just the `rbegin()` inside the loop. – Remy Lebeau Jan 28 '17 at 03:18