根据另一个数组的值对一个数组进行排序

Sort one array based on values of another array?

本文关键字:数组 一个 排序 另一个      更新时间:2023-10-16

我有一个指向对象的指针数组,这些对象是外部代码中类的实例,我不想更改这些对象。

我还有一个int向量,它是通过调用每个对象上的函数生成的。所以我有

A:  [pointerToObj1, pointerToObj2, ... pointerToObjN]

B:  [obj1Int, obj2Int, ..... objNInt]

如何轻松地对A进行排序,使其按B的值进行排序。我有可用的boost。

如果B是

[3, 1, 2]

我想把A按的顺序排序

[pointerToObj2, pointerToObj3, pointerToObj1]

在javascript中,你可以像一样做到这一点

B.sort(function(a,b){return A[B.indexOf(a)] < A[B.indexOf(b)];});
  1. 制作一个包含a&B.

    vector<pair<pointerToObjType, int>> order(N);
    for (int i=0; i<N; ++i){
        order[i] = make_pair(A[i], B[i]);
    }
    
  2. 创建自定义比较器来对配对向量进行排序。

    struct ordering {
        bool operator ()(pair<pointerToObjType, int> const& a, 
                         pair<pointerToObjType, int> const& b) {
            return a.second < b.second;
        }
    };
    
  3. 对配对向量进行排序。

    sort(order.begin(), order.end(), ordering());
    
  4. 所有已排序的A都可以使用order[i].first进行访问。

一个选项是将"分数"数组存储在std::map<MyObject, int> scores中。现在你可以创建一个比较

bool compare(const MyObject* lhs, const MyObject* rhs) {
    return scores[*lhs] < scores[*rhs];
}

现在你只需做

std::sort(vectorOfObjects.begin(), vectorOfObjects.end(), compare);

不幸的是,这需要scores是全局变量,或者scorescompare被打包到同一个类中。

也许更好的方法是使用lambda:

std::sort(vectorOfObjects.begin(), vectorOfObjects.end(),
    [&scores] (const MyObject* lhs, const MyObject* rhs) {scores[*lhs] < scores[*rhs];});

这允许您将scores声明为局部变量,并在lambda中捕获它。

此解决方案的一个缺点是,为了使用MyObject类作为std::map的键,必须为该类实现operator<()(或传递给std::map构造函数的比较器)。幸运的是,您可以将其写成一个全局函数,而不必更改类本身。然而,这需要以某种方式直接比较对象。

相关文章: