簡體   English   中英

用一個變量的最小值提取結構數組

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM