I'm trying to move each element that has x value to the beginning of vector so that all the element that has x value is at the front of the vector, but it is not working , so can you tell me what I've done wrong, please?
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
template <typename Container, typename Arg>
void move_x(Container& c, Arg x)
{
typename Container::iterator it = find(c.begin(), c.end(), x);
if (it!=c.end()) {
c.insert(c.begin(), *it);
remove (it, c.end(), x);
}
}
int main()
{
int x=1;
vector <int> v{1,2,4,6,7,1,3,1,1,8,9};
move_x(v, x);
for(auto i:v)
cout<<v[i];
return 0;
}
and I'm getting this output when I run it
411613848811
Once you insert into the container, the iterator is no longer valid
c.insert(c.begin(), *it); // This invalidates 'it'
remove (it, c.end(), x); // oops! trying to use invalid iterator
Using std::rotate provides better alternative, which doesn't invalidate the iterators:
template <typename Container, typename Arg>
void move_x(Container& c, Arg x)
{
typedef typename Container::iterator It;
It write_it = c.begin(), read_it = c.begin();
for (;;) {
It found_it = find(read_it, c.end(), x);
if (found_it==c.end()) break;
read_it = found_it;
++read_it;
std::rotate(write_it,found_it,read_it);
++write_it;
}
}
As long as you are dealing with simple items like ints, this is a good approach:
template <typename Container, typename Arg>
void move_x(Container& c, Arg x)
{
typename Container::reverse_iterator it = std::remove(c.rbegin(),c.rend(),x);
for (;it!=c.rend();++it) {
*it = x;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With