【问题标题】:std::sort comparator which sees the element's (original) indexstd::sort 比较器查看元素的(原始)索引
【发布时间】:2014-02-06 15:23:06
【问题描述】:

我想std::partial_sort_copy() 一个数组,但使用自定义比较器函数。问题是,这个函数同时使用了被比较的数组单元的 和它们的 索引

为了便于讨论,假设我的比较函数类似于

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

(如果你喜欢,我可以让它更做作......)

起初我想使用一个接受pair&lt;size_t, T&gt;s 的比较器对象——但这行不通,因为这意味着我的输出将是这样对的数组,我不希望这样。事实上,我需要不实现任何东西 - 所以不需要数组对、索引或任何类似的东西。

我应该怎么做?

【问题讨论】:

  • 您要解决什么问题?假设您只对vectorarray 进行排序?
  • @Chad:我实际上想做一些更复杂的事情,即使用数组中的索引在另一个数组中查找某些内容,但我不想先进行所有查找和排序一个元组数组。
  • @AbhishekBansal:这是给你的比较器......或者更确切地说,这是我可能想要运行的比较,而不是比较器对象。我不能真正将比较器对象与对一起使用,因为我不必具体化对数组。
  • 所有初始元素都是正数还是有些也可以是负数?
  • @AbhishekBansal:假设有些可能是负面的。无论如何,这不是我要解决的问题,只是一个插图。

标签: c++ arrays sorting comparator c++-standard-library


【解决方案1】:

类似的东西可能会有所帮助。
它创建一个索引数组,然后根据比较器对该数组进行排序(间接到初始数组):

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

【讨论】:

  • 确实,有了索引数组,这一切都变得非常简单,但出于各种原因,我需要避免实现这样的事情。
  • 你看过std::patial_sort的实现吗?您可以将其重写为具有mypartialsort(IT begin, IT end, size_t* dbegin, size_t* dend, Comp comp)(因此输出是输入的排序索引),然后转换回真实类型T)。
  • 如果我没有找到一些聪明的方法来获得我想要的东西,是的,我会解除 partial_sort()partial_copy_sort() 代码并调整它
  • 你怎么能?排序算法将快速改变序列,从而“破坏”您的索引数据。我担心你必须将你的初始索引复制到某个地方,所以这个答案确实是唯一的选择。
  • @ltjax: std::patial_sort_copy 不会改变输入,因此修改后的版本可能会输出输入索引,(并且在与输出 T 相同的位置)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-13
  • 1970-01-01
  • 1970-01-01
  • 2021-10-05
  • 2013-01-04
相关资源
最近更新 更多