gpt4 book ai didi

c++ - 如何在不复制的情况下稳定排序?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:11:45 29 4
gpt4 key购买 nike

为什么 stable_sort 需要复制构造函数? (swap 应该足够了吧?)
或者更确切地说,如何在不复制任何元素的情况下stable_sort 一个范围?

#include <algorithm>

class Person
{
Person(Person const &); // Disable copying
public:
Person() : age(0) { }
int age;
void swap(Person &other) { using std::swap; swap(this->age, other.age); }
friend void swap(Person &a, Person &b) { a.swap(b); }
bool operator <(Person const &other) const { return this->age < other.age; }
};

int main()
{
static size_t const n = 10;
Person people[n];
std::stable_sort(people, people + n);
}

最佳答案

扩展 OP 中的讨论,因为我发现它很有趣,这里有一个解决方案,它仅使用交换对原始 vector 进行排序(通过使用指针包装器对索引进行排序)。

编辑:这是原地交换的解决方案 v2。

编辑(由 OP):不需要 C++11 的 STL 友好版本。

template<class Pred>
struct swapping_stable_sort_pred
{
Pred pred;
swapping_stable_sort_pred(Pred const &pred) : pred(pred) { }

template<class It>
bool operator()(
std::pair<It, typename std::iterator_traits<It>::difference_type> const &a,
std::pair<It, typename std::iterator_traits<It>::difference_type> const &b) const
{
bool less = this->pred(*a.first, *b.first);
if (!less)
{
bool const greater = this->pred(*b.first, *a.first);
if (!greater) { less = a.second < b.second; }
}
return less;
}
};

template<class It, class Pred>
void swapping_stable_sort(It const begin, It const end, Pred const pred)
{
typedef std::pair<It, typename std::iterator_traits<It>::difference_type> Pair;
std::vector<Pair> vp;
vp.reserve(static_cast<size_t>(std::distance(begin, end)));
for (It it = begin; it != end; ++it)
{ vp.push_back(std::make_pair(it, std::distance(begin, it))); }
std::sort(vp.begin(), vp.end(), swapping_stable_sort_pred<Pred>(pred));
std::vector<Pair *> vip(vp.size());
for (size_t i = 0; i < vp.size(); i++)
{ vip[static_cast<size_t>(vp[i].second)] = &vp[i]; }

for (size_t i = 0; i + 1 < vp.size(); i++)
{
typename std::iterator_traits<It>::difference_type &j = vp[i].second;
using std::swap;
swap(*(begin + static_cast<ptrdiff_t>(i)), *(begin + j));
swap(j, vip[i]->second);
swap(vip[j], vip[vip[j]->second]);
}
}

template<class It>
void swapping_stable_sort(It const begin, It const end)
{ return swapping_stable_sort(begin, end, std::less<typename std::iterator_traits<It>::value_type>()); }

关于c++ - 如何在不复制的情况下稳定排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13791458/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com