Removing from a vector of sets

Apr 18, 2014 at 1:49pm
Hello, I have a vector of sets in which I wish to remove a set from the vector, if it contains a certain value, is there any way of doing this?
1
2
3
4
5
for(int j = 0; j <= clauseVector.size(); ++j){
  if(clauseVector[j].find(find) != clauseVector[j].end())
    std::cout << "FOUND: " << propagator << "\n";
    }
  }


This is what I have been using to find the element, but is there a way to remove the set that contains the element?

If needed I can include the full code

Thank you
Apr 18, 2014 at 1:57pm
It almost sounds like you are looking for vector::erase: http://www.cplusplus.com/reference/vector/vector/erase/
Apr 18, 2014 at 2:27pm
Thats what I thought, but im getting segmentation faults

1
2
3
4
for(int j = 0; j <= clauseVector.size(); ++j){
  if(clauseVector[j].find(propagator) != clauseVector[j].end())
    clauseVector.erase (clauseVector.begin()+j);
 }
Apr 18, 2014 at 2:37pm
for(int j = 0; j <= clauseVector.size(); ++j)
The range for j should b 0 to size - 1, you currently have it as 0 to size.
Apr 18, 2014 at 2:39pm
clauseVector[ clauseVector.size() ] is out of bounds.
Also, if you `erase()' an element you shouldn't increment the index (¿do you realize why?)
Apr 18, 2014 at 2:53pm
@Danny Toledo, I have corrected this but am still getting segmentation faults

@ne555, In what way do you mean?

Once I have removed all instances of (find), it will be updated to a new int in order to remove those as well

Thank you both for your time
Apr 18, 2014 at 2:56pm
Something like this (example assumes that propagator is a string):
1
2
3
4
5
6
7
8
9
auto iter = std::find_if( clauseVector.begin(), clauseVector.end(),
                          [propagator] ( const std::set<std::string>& s ) 
                          { return s.find(propagator) != s.end() ; } ) ;

if( iter != clauseVector.end() )
{
    std::cout << "FOUND: " << propagator << "\n";
    clauseVector.erase(iter) ;
}
Apr 18, 2014 at 3:12pm
Propagator is an int, sorry should have said previously

Edit: I tweaked it, and now it works! It will however only delete one instance of propagator, is there anyway to run this as many times as needed to delete all instance of propagator?

Thank you
Last edited on Apr 18, 2014 at 3:19pm
Apr 18, 2014 at 3:32pm
> I tweaked it, and now it works! It will however only delete one instance of propagator
show updated code.

http://www.cplusplus.com/forum/general/129501/#msg699308
Suppose that you've got {&, &, *, *, &} where '*' indicates sets to be erased.
when j=2, you find the first *, and erase it. The resultant vector is {&, &, *, &}
you then increment j, so j=3, find an & and continue.
Apr 18, 2014 at 3:55pm
Ahhhh I see, I don't know why I took that for loop out, this is the updated code, which so far seems to be working

1
2
3
4
5
6
7
8
9
for(int j = 0; j < clauseVector.size(); ++j){
  auto iter = std::find_if(clauseVector.begin(), clauseVector.end(),[propagator]     (const std::set<int> & s){
    return s.find(propagator) != s.end();
    });
  (iter != clauseVector.end()){
    std::cout << "Found: " << propagator << "\n";
    clauseVector.erase(iter);
    }
  }


I apologise for formatting, I am no use at formatting on here

Edit: After running on a larger file, this is very slow
Last edited on Apr 18, 2014 at 3:58pm
Apr 18, 2014 at 4:15pm
> It will however only delete one instance of propagator,
> is there anyway to run this as many times as needed to delete all instance of propagator?

>> After running on a larger file, this is very slow

The erase-remove idiom is canonical. http://en.wikipedia.org/wiki/Erase-remove_idiom

1
2
3
4
5
auto iter = std::remove_if( clauseVector.begin(), clauseVector.end(),
                            [propagator] ( const std::set<int>& s ) 
                            { return s.find(propagator) != s.end() ; } ) ;

clauseVector.erase( iter, clauseVector.end() ) ;
Apr 18, 2014 at 4:30pm
Wow that certainly speeds things up a lot!

Thank you very much!

One step closer to finishing this Unit Clause Propagation algorithm
Topic archived. No new replies allowed.