[英]Extract struct array with smallest value of one variable
所以說我有以下結構
struct BadQuestion
{
float a;
float b;
} BadArray[10];
現在,我需要檢查哪個array [i]具有“ float a”的第二個最小值。 因為我以后需要從數組中以最小的“ float a”提取“ float b”。
我已經看過類似的例子這樣 ,但它似乎有點過分。 有沒有更簡單快捷的方法來實現這一目標?
更新1:
bool cmp(const BadQuestion& lhs, const BadQuestion& rhs)
{
return lhs.a < rhs.a;
}
auto mini = std::min_element(BadArray, BadArray + 10, cmp);
mini->a
這將給我最小值,這是一個整潔的步驟。 但是我需要second
低的值。
簡單的方法很簡單:
// n is assumed to be at least 2
int i0 = array[0].a<array[1].a ? 0 : 1, i1 = 1 - i0;
for (int i=2; i<n; i++) {
if (array[i].a < array[i1].a) {
if (array[i].a < array[i0].a) {
i1 = i0; i0 = i;
} else {
i1 = i;
}
}
}
// i0 is index of smallest a value, i1 is index of second-smallest
而且我非常確定現代編譯器會將其轉換為經過合理優化的機器代碼(但是,對於速度而言,使用floats
並不是一個好主意)。
有兩種解決方案,具體取決於您是否關心訂單。
如果您不關心此操作后任何元素的順序,則可以使用標准算法nth_element 。 它將重新排序您的元素:
template <typename Iter, typename Cmp>
typename std::iterator_traits<Iter>::value_type
nth_smallest_reorder(Iter begin, Iter end, int n, Cmp cmp) {
std::nth_element(begin, begin + n, end, cmp);
return *(begin + n);
}
如果您確實在乎訂購,則可以執行以下兩項操作之一。 首先,您可以直接復制整個數組:
template <typename Iter, typename Cmp>
typename std::iterator_traits<Iter>::value_type
nth_smallest_copy(Iter begin, Iter end, int n, Cmp cmp) {
std::vector<typename std::iterator_traits<Iter>::value_type> cpy(begin, end);
std::nth_element(cpy.begin(), cpy.begin() + n, cpy.end(), cmp);
return cpy[n];
}
或者,您可以保留大小不超過n+1
的運行排序列表:
template <typename Iter, typename Cmp>
typename std::iterator_traits<Iter>::value_type
nth_smallest_no_copy(Iter begin, Iter end, int n, Cmp cmp) {
std::vector<typename std::iterator_traits<Iter>::value_type> n_best;
n_best.reserve(n + 2);
for (; begin != end; ++begin) {
if (n_best.empty() || cmp(*begin, n_best.back())) {
n_best.insert(
std::lower_bound(n_best.begin(), n_best.end(), *begin, cmp),
*begin);
if (n_best.size() > n + 1) n_best.resize(n + 1);
}
}
return n_best.back();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.