使用std :: sort对具有特定条件的2D矢量进行排序

时间:2017-04-16 21:24:36

标签: c++ sorting vector 2d

我遇到了一个编码问题,即使用库std::sort中的algorithm使用所需条件对2D矢量(矩阵)进行排序

例如,假设我有一个2D矢量

1,8,3
1,9,1
1,4,2 
    ^

我希望按第3列排序(例如增长标准) 所以在排序后我想要一个矩阵:

1,9,1
1,4,2
1,8,3
    ^

我知道为了在std::sort中指定排序条件,需要在std::sort中发送第三个函数。如果它是1D vector则不会有问题。我会在std::sort中使用2个参数创建一个lambda,比较它们并返回true / false。

现在你可以看到我面临的问题,如何访问矩阵内的特定元素,在我的第三列元素中,并将它们与std::sort进行比较?

#include <iostream>
#include <vector>
#include <algorithm>

void printMatrix(std::vector<std::vector<int>> m) {
    for(int i = 0; i < m.size(); i++) {
        for(int j = 0; j < m[i].size(); j++) {
            std::cout << m[i][j] << " ";
        }
        std::cout << std::endl;
    }
}

int main() {
    std::vector<std::vector<int>> m{
        {1,8,3},
        {1,9,1},
        {1,4,2}
    };

    std::sort(m.begin(), m.end(), [](int a, int b) { // error
                // ???
    });
    printMatrix(m);

    return 0;
}

我不想使用任何其他外部库来解决这个问题。

非常感谢任何帮助! :)

3 个答案:

答案 0 :(得分:3)

std::sort(m.begin(), m.end(), [](int a, int b) { // error
                // ???
    });

value_typem.begin()返回的迭代器的m.end()std::vector<int>。因此,您的lambda需要为其两个参数采用类型

std::sort(m.begin(), m.end(), 
        [](const std::vector<int>& a, const std::vector<int>& b) {
               return a.at(2) < b.at(2);
    });

注意:我在这里使用at()成员函数而不是运算符[]来防止UB,如果您错误地尝试在无效索引中进行排序。

Demo

答案 1 :(得分:2)

如果要对std::vector<std::vector<int>>进行排序,则容器的项目类型为std::vector<int>,而不是int。因此,您不能将lambda与声明

一起使用
[](int a, int b) { ... }

对这样的容器进行排序。您需要在声明

中使用lambda
[](std::vector<int> a, std::vector<int> b) { ... }

[](std::vector<int> const& a, std::vector<int> const& b) { ... }

使用第一个版本非常昂贵,因为每次调用std::vector时,最终都会复制lambda。因此,建议使用第二个版本。

std::sort(m.begin(), m.end(), [](std::vector<int> const& a,
                                 std::vector<int> const& b) {
   return a.back() < b.back();
});

答案 2 :(得分:0)

虽然不是最有效的解决方案,但最简单的方法是转置您的2D矢量(也称为矩阵)对每个矢量进行排序,然后再次转置。这是一个经过测试的工作函数,可以为您完成此任务:

def dashboard
  @all_orders = Order.all
  if params[:status] == "ordered"
    @orders = Order.where(status: "ordered")
  elsif params[:status] == "paid"
    @orders = Order.where(status: "paid")
  elsif params[:status] == "completed"
    @orders = Order.where(status: "completed")
  elsif params[:status] == "cancelled"
    @orders = Order.where(status: "cancelled")
  else    
    @orders = Order.all
  end
end

同样,这不是按列对矩阵进行排序的最有效或最现代的方法,但它有效且易于理解。