按对象的变量对对象的向量进行排序

Sorting vector of objects by object's variable

我有一个对象向量。这些对象中的每一个都有 2 个字段(其值可以重复),例如:

//myClass name = myClass(x,y)
myClass obj1 = myClass(2,5);
myClass obj2 = myClass(2,4);
myClass obj3 = myClass(1,5);
myClass obj4 = myClass(3,2);
 
std::vector<myClass> myVector;
 
myVector.push_back(obj1);
myVector.push_back(obj2);
myVector.push_back(obj3);
myVector.push_back(obj4);

我想对向量进行排序。首先,它应该按第一个值排序。如果第一个变量的值相同,则应按第二个变量排序。排序后的向量应该是这样的:

  1. obj3 //(1,5)
  2. obj2 //(2,4)
  3. obj1 //(2,5)
  4. obj4 //(3,2)

我用冒泡排序写了这个简单的代码:

for (int i = 0; i < myVector.size(); i++)
    {
        for (int j = 0; j < myVector.size() - 1; j++)
        {
            if (myVector[j].x < myVector[j + 1].x)
                std::swap(myVector[j], myVector[j + 1]);
        }
    }

现在 myVector 按第一个值排序,但是如何对第一个值相同的元素按第二个值排序?就像例子一样?

您可以将 if 语句更改为:

if ( (myVector[j].x == myVector[j + 1].x) ? (myVector[j].y < myVector[j + 1].y) : (myVector[j].x < myVector[j + 1].x)  ) 

您可以尝试类似的方法:

for (int i = 0; i < myVector.size(); i++)
    {
        for (int j = 0; j < myVector.size() - 1; j++)
        {
            if (myVector[j].x < myVector[j + 1].x)
            {
                std::swap(myVector[j], myVector[j + 1]);
            }
            else if (myVector[j].x == myVector[j + 1].x)
            {
                if (myVector[j].y < myVector[j + 1].y)
                    std::swap(myVector[j], myVector[j + 1]);
            }
        }
    }

对于初学者来说,如果你想按升序对向量进行排序,那么至少你需要按以下方式使用 if 语句

        if (myVector[j+1].x < myVector[j].x)
            std::swap(myVector[j], myVector[j + 1]);

而不是

        if (myVector[j].x < myVector[j + 1].x)
            std::swap(myVector[j], myVector[j + 1]);

一个简单的方法是使用在 header <tuple>.

中声明的标准函数 std::tie

例如

#include <tuple>

//...

for (int i = 0; i < myVector.size(); i++)
{
    for (int j = 0; j < myVector.size() - 1; j++)
    {
        if ( std::tie( myVector[j+1].x, myVector[j+1].y ) < 
             std::tie( myVector[j].x, myVector[j].y ) )
            std::swap(myVector[j], myVector[j + 1]);
    }
}

您可以使用标准算法 std::sort 而不是手动编写的循环。例如

#include <tuple>
#include <vector>
#include <iterator>
#include <algorithm>

//...

std::sort( std::begin( myVector ), std::end( myVector ),
           []( const auto &obj1, const auto &obj2 )
           {
               return std::tie( obj1.x, obj1.y ) < std::tie( obj2.x, obj2.y );
           } );