使用容器中的第n个元素,但使用另一个键

use n_th element in a container, but with another key

本文关键字:元素 另一个      更新时间:2023-10-16

我有两个向量。一个实际保存数据(比如浮点数),另一个保存索引。我想在nth_element传递下标向量,但是我想让比较是由实际保存数据的向量来完成的。我在考虑一个函子,但我猜它只提供()运算符。我通过使数据向量成为一个全局向量来实现这一点,但当然这不是我想要的。

std::vector<float> v;                                   // data vector (global)
bool myfunction (int i,int j) { return (v[i]<v[j]); } 
int find_median(std::vector<int> &v_i)
{
    size_t n = v_i.size() / 2;
    nth_element(v_i.begin(), v_i.begin()+n, v_i.end(), myfunction);
    return v_i[n];
}

可以使用以下函子:

class comp_with_indirection
{
public:
    explicit comp_with_indirection(const std::vector<float>& floats) :
        floats(floats)
    {}
    bool operator() (int lhs, int rhs) const { return floats[lhs] < floats[rhs]; }
private:
    const std::vector<float>& floats;
};

然后你可以这样使用:

int find_median(const std::vector<float>& v_f, std::vector<int> &v_i)
{
    assert(!v_i.empty());
    assert(v_i.size() <= v_f.size());
    const size_t n = v_i.size() / 2;
    std::nth_element(v_i.begin(), v_i.begin() + n, v_i.end(), comp_with_indirection(v_f));
    return v_i[n];
}

注意:在c++ 11中,你可以使用lambda来代替命名函数类。

int find_median(const std::vector<float>& v_f, std::vector<int> &v_i)
{
    assert(!v_i.empty());
    assert(v_i.size() <= v_f.size());
    const size_t n = v_i.size() / 2;
    std::nth_element(
        v_i.begin(), v_i.begin() + n, v_i.end(),
        [&v_f](int lhs, int rhs) {
            return v_f[lhs] < v_f[rhs];
        });
    return v_i[n];
}
相关文章: