std::sort for a 2D vector in c++

std::sort for a 2D vector in c++

本文关键字:vector in c++ 2D sort for std      更新时间:2023-10-16

我有一个 2D 向量InputVector定义如下:

vector< vector<int> > InputVector(MAX_ITER, vector<int>(inN));

还有另一个向量CR定义如下:

vector<int> CR(MAX_ITER);

CR[i]是与InputVector[i]相关的属性(请注意i两者的0MAX_ITER-1可能有所不同)。现在我想按CR的降序对InputVector进行排序,即,如果CR[j]是所有CR's中最高的,InputVector[j]应该是排序后的新InputVector[0]。这可以使用algorithm中定义的std::sort来完成吗?

这是一项非常奇怪的任务,但可以做到。

我会说 - 将 CR[j] 值

push_back为 InputVector[j],然后编写一个自定义的"less"函数来比较最后一个元素并pop_back CR[j] 值。像这样:

但似乎你真的应该重新考虑你如何存储你的数据 - 你需要这样的逻辑是一个警告。

#include <vector>
#include <algorithm>
#include <iostream>
#include <cassert>
using namespace std;
typedef vector<int> vi;
typedef vector<vi> vvi;
struct last_cmp
{
    bool operator()(const vi &lhs, const vi &rhs)
    {
        return lhs.back() > rhs.back();
    }
};
void weird_sort(vvi &InputVector, const vi &CR)
{
    assert(InputVector.size() == CR.size());
    for (size_t i = 0; i < InputVector.size(); i++)
        InputVector[i].push_back(CR[i]);
    sort(InputVector.begin(), InputVector.end(), last_cmp());
    for (size_t i = 0; i < InputVector.size(); i++)
        InputVector[i].pop_back();
}
int main()
{
    vvi InputVector;
    vi CR;
    InputVector.push_back(vector<int>(5, 0));
    InputVector.push_back(vector<int>(5, 1));
    InputVector.push_back(vector<int>(5, 2));
    InputVector.push_back(vector<int>(5, 3));
    InputVector.push_back(vector<int>(5, 4));
    CR.push_back(3);
    CR.push_back(2);
    CR.push_back(0);
    CR.push_back(1);
    CR.push_back(4);
    weird_sort(InputVector, CR);
    for (int i = 0; i < InputVector.size(); i++)
        cout << InputVector[i][0] << endl;
}

我认为一个新类或使用 pair 会更好,但如果你真的想这样做

std::sort(InputVector.begin(), InputVector.end(), 
    [&CR,&InputVector](std::vector<int> &a, std::vector<int> &b){
        auto pos_a = &a - &(*InputVector.begin());
        auto pos_b = &b - &(*InputVector.begin());
        return (CR[pos_a] < CR[pos_b]);}
        );

这在我所做的小测试中有效,但我认为这可能是危险的。

在您的问题下的评论中,您澄清了您希望将两个数组分开而不是将它们组合在一起,并且您希望对CRInputVector进行排序。在这种情况下,最简单的方法是创建一个临时数组,将两个数组压缩为一个,使用 std::sort ,然后解压缩回原来的两个数组。

压缩和解压缩不应该太慢:它们是 O(n),而排序是 O(n log n)。此外,假设您的大部分数据包含在嵌套vector<int> in InputVector 中,可以使用 vector::swap 将数据移入和移出临时数组,顾名思义,它围绕底层数据交换而不是复制它。

#include <vector>
using std::vector;
#include <algorithm>
void Sort(vector< vector<int> > &InputVector, vector<int>& CR) // assumes vectors the same size
{
    struct CRIntVec
    {
        int CR;
        vector<int> IntVec;
        bool operator<(const CRIntVec& rhs) const
        { return CR > rhs.CR; } // sort in descending order
    };
    vector<CRIntVec> combinedVec(InputVector.size());
    // Copy CR to combined vector but for efficiency swap in InputVector 
    for(int i=0; i<InputVector.size(); ++i) {
        combinedVec[i].CR = CR[i];
        combinedVec[i].IntVec.swap(InputVector[i]);
    }
    // Sort the combined vector
    std::sort(combinedVec.begin(), combinedVec.end());
    // Copy back from combined vector to CR, once again swapping for efficiency
    for(int i=0; i<InputVector.size(); ++i) {
        CR[i] = combinedVec[i].CR;
        combinedVec[i].IntVec.swap(InputVector[i]);
    }
}

你可以,但它会非常昂贵。你必须对InputVector CR的每个成员进行顺序搜索,以获得它的相对排序值。这并非不可能,但效率非常低。

为了提高效率,CR制作地图或哈希表。