简体   繁体   中英

std::sort comparator which sees the element's (original) index

I would like to std::partial_sort_copy() an array, but using a custom comparator function. The thing is, this function uses both the values of the array cells being compared and their indices .

For the sake of discussion, suppose my comaprison function is something like

template <typename T>
bool myCompare(size_t lhs_index, const T& lhs, size_t rhs_index, const T& rhs) {
    T lhs_compound = lhs * (lhs_index % 2 ? -1 : 1);
    T rhs_compound = rhs * (lhs_index % 2 ? -1 : 1);
    return (lhs_compound <= rhs_compound);
}

(I can make it more contrived if you like...)

At first I thought of using a comparator object which takes pair<size_t, T> s - but that won't work, since it means my output will be an array of such pairs, and I don't want that. In fact, I need to not materialize anything - so no arrays of pairs, or of indices, or any such thing.

What should I do instead?

Something like that may help.
It create an array of indexes, then sort this array according to the comparator (with indirection to initial array):

template <typename IT, typename Comp>
struct MyCmp
{
    explicit Cmp(const IT it, Comp& comp) : it(it), comp(comp) {}
    bool operator (std::size_t lhs, std::size_t rhs) const
    {
        return comp(lhs, *(it + lhs), rhs, *(it + rhs));
    }
    const IT it;
    Comp comp;
};

template<typename IT, typename IT2, typename Comp>
void mypartialsort(IT begin, IT end, IT2 dbegin, IT2 dend, Comp comp)
{
    std::vector<size_t> indexes;
    for (size_t i = 0, size = end - begin; i != size; ++i) {
        indexes.push_back(i);
    }
    MyCmp<IT, Comp> mycomp(begin, comp);
    const std::size_t min_size = std::min(end - begin, dend - dbegin);
    std::partial_sort(v.begin(), v.begin() + d, v.end(), mycomp);

    for (std::size_t i = 0; i != min_size; ++i, ++dbegin) {
        *dbegin = *(begin + v[i]);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM