Reputation: 31
I want to save the indices of my bool vector where the vector element is false.
I have the following code:
vector<bool> incumbent_solution; // (0,0,0,1,1,0,0)...
vector<int> I_minus_S(incumbent_solution.size());
auto it = copy_if(incumbent_solution.begin(), incumbent_solution.end(),
I_minus_S.begin(), [&incumbent_solution](auto i) {if (incumbent_solution[i] == 0] return i; });
I_minus_S.erase(it, I_minus_S.end());
But it only stores True in my Vector and not the indices. What is my lambda doing wrong?
Upvotes: 0
Views: 2242
Reputation: 23784
std::vector< bool > vb = { 0,0,0,1,1,0,0 };
std::vector< int > vi;
unsigned counter = 0;
for( bool b : vb ){
if( !b ){
vi.push_back( counter );
}
++counter;
}
for( int& i : vi ){
std::cout << i << '\n';
}
std::copy_if
accepts an UnaryFunction that should return true
or false
. It is better to use a simple for
.
If you are demanding to use algorithm
library, you can use transform
std::vector< bool > vb = { 0,0,0,1,1,0,0 };
std::vector< int > vi;
int counter = -1;
std::transform( vb.begin(), vb.end(), std::back_inserter( vi ),
[&](const bool b ){
counter++;
if( !b ) return counter;
}
);
but the problem with that is, for true
condition returns 0
to the index of vi
. Although you can use -1
and later remove them inside vi
[&](const bool b ){
counter++;
if( !b ) return counter;
else return -1;
}
but still a simple for
is a better solution.
Upvotes: 1
Reputation: 4473
The std::copy_if
works differently than you expected, it passes the actual element to the predicate and copies it into the second container if the predicate returns true
.
If you want indexes, use a simple for
loop:
std::vector<bool> incumbent_solution { 0, 0, 0, 1, 1, 0, 0, 1, 1 };
std::vector<int> I_minus_S(incumbent_solution.size());
std::size_t last = 0;
for(std::size_t index = 0; index < incumbent_solution.size(); ++index) {
if(incumbent_solution[index] == false)
I_minus_S[last++] = index;
}
I_minus_S.erase(I_minus_S.begin() + last, I_minus_S.end());
Upvotes: 0