我的向量类型为std::vector<std::pair<int, std::string>>
。我只是想按降序排列(通过使用std::pair
对象的第一个int值),同时保持它的稳定,以便按插入顺序保留相等的数字。
Fe:
如果我有 :。 5,3a,4,3b,6
我希望将其排序:6,5,4,3a,3b
但是它似乎无法正常工作。排序功能按升序对其进行排序。所以我想做的是排序,然后以相反的顺序进行处理。但是后来我又得到了相反的值,这很不稳定,对我也不好。因此,我尝试先反转整个向量,然后再对其进行排序,然后以相反的顺序进行处理,但我不知道为什么它不起作用? 看起来即使我先反转向量,排序函数也会按插入顺序更改它。
无论如何,我如何实现自己的目标。递减的向量,同时保持其稳定。
编辑:对所有说使用稳定排序的人。这也无济于事。我尝试过这个。我的问题不只是稳定的顺序,而是递减的顺序并且稳定。他们中没有一个能做到这一点。
答案 0 :(得分:5)
std::sort
按升序对[first,last)范围内的元素进行排序。 相等元素的顺序不能保证得到保留。
因此,相等元素的顺序可能会或可能不会更改。您正在寻找的是std::stable_sort
按升序对[first,last)范围内的元素进行排序。 保证保留等效元素的顺序。
如果要对向量进行降序稳定排序,则可以选择使用rbegin和rend。顺序将相反;这是一个示例实现:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
class A {
public:
A(int d = 0, const std::string& n = "a"): data(d), name(n) {}
friend bool operator< (const A& par1, const A& par2) {
return par1.data < par2.data;
}
A& operator= (const A& other) {
data = other.getData();
name = other.getName();
return *this;
}
std::string getName() const {
return name;
}
int getData() const {
return data;
}
private:
int data = 0;
std::string name;
};
int main()
{
A a(7, "a"), b(2, "b"), c(3, "c"), d(2, "d"), e(3, "e"), f(6, "f");
std::vector<A> iv {a, b, c, d, e, f};
std::stable_sort(iv.rbegin(), iv.rend());
for (const auto e : iv) {
std::cout << e.getName() << " ";
}
std::cout << std::endl;
return 0;
}
输出:
a f c e b d
可以看出,相同元素的顺序被保留,向量以相反的顺序排序。
另一个选择是使用std::greater。它在<functional>
标头中定义,您将需要operator>。这是一个示例实现:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
class A {
public:
A(int d = 0, const std::string& n = "a"): data(d), name(n) {}
friend bool operator< (const A& par1, const A& par2) {
return par1.data < par2.data;
}
friend bool operator> (const A& par1, const A& par2) {
return par1.data > par2.data;
}
A& operator= (const A& other) {
data = other.getData();
name = other.getName();
return *this;
}
std::string getName() const {
return name;
}
int getData() const {
return data;
}
private:
int data = 0;
std::string name;
};
int main()
{
A a(7, "a"), b(2, "b"), c(3, "c"), d(2, "d"), e(3, "e"), f(6, "f");
std::vector<A> iv {a, b, c, d, e, f};
std::stable_sort(iv.begin(), iv.end(), std::greater<A>());
for (const auto e : iv) {
std::cout << e.getName() << " ";
}
std::cout << std::endl;
return 0;
}
输出:
a f c e b d
如果您要基于第一个元素对std::vector<std::pair<int, std::string>>
类型的对象进行反向和稳定排序(如此处所示),则可以使用lambda:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <utility>
#include <functional>
using pis = std::pair<int, std::string>;
int main()
{
pis a{5, "a"}, b{3, "b"}, c{4, "c"}, d{3, "d"}, e{3, "e"};
std::vector<pis> iv {a, b, c, d, e};
std::stable_sort(iv.begin(), iv.end(), [](const pis p1, const pis p2) {return p1.first > p2.first;});
for (const auto e : iv) {
std::cout << e.second << "(" << e.first << ")" << " ";
}
std::cout << std::endl;
return 0;
}
输出:
a(5) c(4) b(3) d(3) e(3)
要点
1.请注意,pis
是std::pair<int, std::string>
的{{3}}
2.在lambda中使用>
代替<
是导致向量反转的原因。
答案 1 :(得分:3)
为什么排序功能会更改相同值的顺序?
因为std::sort()
的{{3}}这样说:
按升序对[first,last)范围内的元素进行排序。 不能保证相等元素的顺序被保留。
重点是我的。如果您需要保留订单,请使用documentation
按升序对[first,last)范围内的元素进行排序。 保证等同元素的顺序得到保留。
注意:
Sort函数按升序对其进行排序。所以我想做的是排序,然后以相反的顺序进行处理。
这是一种错误的方法-您放空顺序不是因为std::stable_sort()
“不起作用”,而是因为您在排序之后反转了向量,只需使用std::stable_sort()
即可接受自定义比较器并提供一个(最佳)使用lambda的选项),以降序对其进行排序。然后std::stable_sort()
将保留相等元素的顺序,并且您无需反转向量。