Поиск минимального ненулевого элемента массива
Есть массив std::vector<unsigned int> mas, нужно найти минимальный среди ненулевых элементов.
Просто минимальный легко находится таким способом:
auto min_pos = std::min_element (mas.begin (), mas.end (), [&](unsigned int a, unsigned int b){ return a < b; });
unsigned int m = *min_pos;
Я специально написал с лямбдой, потому что (мне кажется) нужно что-то хитрое в неё добавить, что именно - что-то не могу сообразить.
Модифицировать массив нельзя, если бы было можно - я бы сделал ему std::remove и далее по накатанной.
Ответы (3 шт):
Автор решения: zcorvid
→ Ссылка
Придумал такой вариант
auto min_pos = std::min_element (mas.begin (), mas.end (), [&](int a, int b){ return a != 0 && a < b; });
if (min_pos != mas.end ())
std::cout << "минимум = " << mas[*min_pos] << std::endl;
else
std::cout << "нету ненулевых элементов" << std::endl;
Но, возможно, есть более правильный способ?
Автор решения: Stanislav Volodarskiy
→ Ссылка
Зададим полный порядок, в котором нулевые значения больше любых других:
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> a = {0, 1, 2};
auto min_pos = std::min_element(a.begin(), a.end(), [](auto a, auto b){
// nonzero < zero
if ((a != 0) && (b == 0)) {
return true;
}
// !(zero < nonzero)
if ((a == 0) && (b != 0)) {
return false;
}
// zero < zero OR
// nonzero < nonzero
return a < b;
});
std::cout << *min_pos << '\n';
}
Лямбда рефакторится до вида, который Harry уже привел в комментарии и ответе:
auto min_pos = std::min_element(a.begin(), a.end(), [](auto a, auto b){
return (a != 0) && ((b == 0) || (a < b));
});
Автор решения: Harry
→ Ссылка
Буду предельно краток :), вот она, лямбда:
[&](int a, int b){ return a && (!b || a < b); }