use n_th element in a container, but with another key

泪湿孤枕 提交于 2019-12-20 04:36:11

问题


I have two vectors. One that actually holds the data (let's say floats) and one that holds the indices. I want to pass at nth_element the indices vector, but I want the comparison to be done by the vector that actually holds the data. I was thinking about a functor, but this provides only the () operator I guess. I achieved that by making the data vector a global one, but of course that's not desired.

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];
}

回答1:


You may use a functor like:

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;
};

And then you may use it like:

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];
}

Note: with C++11, you may use lambda instead of named functor class.

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];
}


来源:https://stackoverflow.com/questions/23471045/use-n-th-element-in-a-container-but-with-another-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!