C++ 为什么排序函数会更改相同值的顺序?

C++ 为什么排序函数会更改相同值的顺序?,c++,sorting,programming-languages,C++,Sorting,Programming Languages,我有类型为std::vector的向量。我只是尝试将其按降序排列(通过使用std::pair对象的第一个int值),同时保持其稳定,以便在插入顺序中保持相同的数字 Fe: 如果我有:。5、3a、4、3b、6 我要订购:6、5、4、3a、3b 但它似乎不起作用。Sort函数按递增顺序对其进行排序。所以我想做的是排序,然后按相反的顺序取它们。但我也会得到同样的值,顺序相反,这不稳定,对我也不好。所以我试着先反转整个向量,然后对它排序,然后按相反的顺序取它们,但我不知道为什么它不起作用? 看起来排序函

我有类型为
std::vector
的向量。我只是尝试将其按降序排列(通过使用
std::pair
对象的第一个int值),同时保持其稳定,以便在插入顺序中保持相同的数字

Fe:
如果我有:。5、3a、4、3b、6
我要订购:6、5、4、3a、3b

但它似乎不起作用。Sort函数按递增顺序对其进行排序。所以我想做的是排序,然后按相反的顺序取它们。但我也会得到同样的值,顺序相反,这不稳定,对我也不好。所以我试着先反转整个向量,然后对它排序,然后按相反的顺序取它们,但我不知道为什么它不起作用? 看起来排序函数会按插入顺序更改它,即使我先反转向量

无论如何,我是如何实现我的目标的。在保持稳定的情况下,顺序递减的向量

编辑:给所有说使用稳定排序的人。这也于事无补。我试过了。我的问题不只是关于稳定的顺序,而是关于降序和稳定的。他们中没有人能做到这一点

为什么排序函数会更改相同值的顺序

因为for
std::sort()
这样说:

按升序对[第一、最后]范围内的元素进行排序。不保证保留相等元素的顺序。

重点是我的。如果你需要保持秩序,请使用

按升序排列[第一、最后一个]范围内的元素。保证保留等效元素的顺序。

注:

排序函数按递增的顺序对其排序,所以我要做的是排序,然后按相反的顺序进行排序

这是一种错误的方法-您乱序不是因为
std::stable_sort()
“不起作用”,而是因为您在排序后反转向量,只需使用
std::stable_sort()
,它接受自定义比较器,并提供一个(使用lambda的最佳选项)按降序排序。然后使用
std::stable_sort())
将保留相等元素的顺序,不需要反转向量

按升序对[第一,最后]范围内的元素进行排序。 不保证保留相等元素的顺序。

因此,相等元素的顺序可能会改变,也可能不会改变

按升序对[第一,最后]范围内的元素进行排序。 保证保留等效元素的顺序。

如果要按降序对向量进行稳定排序,其中一个选项是使用and。顺序将颠倒;下面是一个示例实现:

#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;
}
#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;
}
可以看出,对于相等的元素,顺序保持不变,而向量按相反的顺序排序

另一个选项是使用。它在
标题中定义,您将需要。下面是一个示例实现:

#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;
}
#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;
}
编辑: 如果要根据第一个元素对类型为
std::vector
的对象进行反转和稳定排序(这里似乎是这样),可以使用:

突出显示
1.请注意,
pis
是一个for
std::pair


2.使用
而不是
std::sort
并不保证比较为相等的值的相对顺序会被保留。如果需要保留值的顺序,则必须在排序比较器函数中包含所有逻辑。结束。实际上有一个
std::stable_sort
。请发布一个
stable\u sort
“不起作用”的ows。您描述的是您所拥有的,但描述不是真实的——让我们看看实际的代码示例。@bilanush——您被要求发布代码,但您尚未发布。我们对您声称的
stable\u sort
不起作用的说法提出异议,而问题实际上是“用户错误”@bilanush我们不知道为什么你的技巧没有。但是正确的答案-不要使用这个技巧,而是使用
std::sort
std::stable_sort
properlyStable排序没有帮助。你没有正确阅读问题。我问的不是稳定的升序,而是关于降序和稳定的。@bilanush it d确实,升序或降序取决于比较器,稳定排序将保持比较器视为相等的元素顺序。我尝试过,但没有帮助。注意,我使用的是对向量。然后你尝试了错误,你应该用你尝试过的示例数据和代码、预期结果和得到的结果创建一个问题。如果你有对和need第一个元素按降序排列,但第二个元素按升序排列,写入适当的比较器,再次使用和数据创建一个问题sample@bilanush除了我的回答,你只是做了错误的排序。稳定排序没有帮助。你没有正确阅读问题。我问的不是稳定的升序,而是降序和降序stable@bilanush在代码中添加了一种在稳定排序时反转排序的方法如何检查它是否稳定?这一点都不好。它只是排序和反转。为什么它会稳定?接受并投票
#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)