I need to get the min element value (x) in the vector.
Given the index i of the x, I need to check if the flag[I] == 0
to return I.
I don't want to sort or discard any value because I need its ordinal number, I need the vector to hold its "structure" how can I get the index of that min_element?
example
A = {1, 2, 3, 4, 0, -1}
flag = {0, 0, 1, 0, 1, 1}
min_element = -1, but flag[5] = 1 same for element 0 so min_element is 1 and index 0
CodePudding user response:
You can have a filter view of A
with only the elements where flag
is 0, and pass that to std::ranges::min
.
With C 23 range views:
namespace views = std::ranges::views;
// min is undefined if passed an empty range
assert(std::ranges::any_of(flag, [](auto f){ return f == 0; });
auto value = std::ranges::min(views::zip(A, flag)
| views::filter([](auto && item){ return std::get<1>(item) == 0; })
| views::transform([](auto && item){ return std::get<0>(item); }));
CodePudding user response:
If you store both arrays in a single std::vector<std::pair<int,int>>
you can use std::min_element
directly:
#include <vector>
#include <iostream>
#include <algorithm>
int main() {
std::vector<int> A = {1, 2, 3, 4, 0, -1};
std::vector<int> flag = {0, 0, 1, 0, 1, 1};
std::vector<std::pair<int,int>> flag_and_A;
for (int i=0;i<A.size(); i){
flag_and_A.push_back({flag[i],A[i]});
}
auto it = std::min_element(flag_and_A.begin(),flag_and_A.end());
std::cout << it->second;
}
std::pair::operator<
induces a lexicographical odering, ie first first
(the flag) is compared then second
(A
). In other words, entries with flag == 0
are considered smaller than entries with flag == 1
.
If you do not want to construct the vector<pair<int,int>>
you can still use std::pair::operator<
:
int main() {
std::vector<int> A = {1, 2, 3, 4, 0, -1};
std::vector<int> flag = {0, 0, 1, 0, 1, 1};
auto it = std::min_element(A.begin(),A.end(),[&](const int& a,const int& b){
unsigned index_a = &a - &A[0];
unsigned index_b = &b - &A[0];
return std::make_pair(flag[index_a],a) < std::make_pair(flag[index_b],b);
});
std::cout << *it;
}
CodePudding user response:
I think you can make a copy of the vector, to sort, record the min-element,and then clear the copy vector.