簡體   English   中英

使用std :: sort對具有特定條件的2D向量進行排序

[英]Sorting a 2D vector with specific criteria using std::sort

我遇到了一個編碼問題,涉及使用庫algorithm std::sort使用所需標准對2D向量(矩陣)進行std::sort

例如,假設我有一個2D矢量

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

我想按第三列對其進行排序(例如,增長標准),所以在排序之后,我想要一個矩陣:

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

我知道,為了在std::sort指定排序標准,需要在std::sort發送第三個函數。 如果它是一維vector那將不是問題。 我將在帶有2個參數的std::sort內部創建一個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;
}

我不想使用任何其他外部庫來解決此問題。

任何幫助都非常感謝! :)

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

m.begin()m.end()返回的迭代器的value_typestd::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()成員函數而不是operator []來防止UB。

演示

當您要對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) { ... }

使用第一個版本很昂貴,因為最終會為每個lambda調用復制std::vector 因此,建議使用第二個版本。

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

盡管這不是最有效的解決方案,但最簡單的方法是將2D向量(也稱為矩陣)轉置,然后對每個向量排序。 這是一個經過測試的工作功能,可以為您完成此任務:

template<typename T>
void sortColumns(vector<vector<T> > &v){
    vector<vector<T> > rv(v[0].size(), vector<T>(v.size()));
    for(int i = 0; i < v.size(); i++){
        for(int j = 0; j < v[i].size(); j++){
            rv[j][i] = v[i][j];
        }
    }
    for(int i = 0; i < rv.size(); i++){
        sort(rv[i].begin(), rv[i].end());
        for(int j = 0; j < rv[i].size(); j++){
            v[j][i] = rv[i][j];
        }
    }
}

同樣,這不是按列對矩陣進行排序的最有效或最現代的方法,但它有效且易於理解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM