C++sort如何使用lambda表达式对一维vector和二维vector进行排序
文章目錄
- 一維vector排序
- 二維vector排序
- Lambda的語法
- Capture(用以訪問外部作用域)
問題:今天刷題的時候,需要對二維vectorn×2_{n\times 2}n×2?按照第二關鍵字排序。看到別人使用lambda表達式進行排序,這里筆者記錄一下。
下面先給出使用lambda表達式排序的例子,后面給出lambda表達式語法等基礎知識。
一維vector排序
對vector< int > temp;按照從大到小排序
sort(temp.begin(),temp.end(),[](int a ,int b){return a>b;});一維vector使用lambda表達式排序的測試程序:
#include<bits/stdc++.h> using namespace std;const int N =2; int main(){vector<vector<int>> vec;vector<int>temp;temp={1,2,4,5,3};sort(temp.begin(),temp.end(),[](int a ,int b){return a>b;});for(auto p:temp)cout<<p<<" ";cout<<endl; }輸出結(jié)果:5 4 3 2 1
二維vector排序
默認按照第一關鍵字進行從小到大排序
sort(vec.begin(),vec.end());對二維vector : vector< vector>> vec(每列兩個元素)按照第二關鍵字從大到小進行排序
sort(vec.begin(),vec.end(),[](vector<int>a, vector<int> b){return a[1]>b[1];});按照第一關鍵字從大到小排序
sort(vec.begin(),vec.end(),[](vector<int>a, vector<int> b){return a[0]>b[0];});測試代碼
#include<bits/stdc++.h> using namespace std;const int N =2;//每列2個元素 int main(){vector<vector<int>> vec;vec.push_back({3,10});vec.push_back({1,8});vec.push_back({5,3});vec.push_back({20,1});sort(vec.begin(),vec.end(),[](vector<int>a, vector<int> b){return a[1]>b[1];});//下標遍歷for(int i=0;i<vec.size();i++){for(int j=0;j<N;j++)cout<<vec[i][j]<<" ";cout<<endl;} }輸出結(jié)果
3 10 1 8 5 3 20 1下面是一些lambda表達式語法的補充。
C++11引入了lambda,允許inline函數(shù)的定義式被用作一個參數(shù),或是一個local對象。
Lambda改變了C++標準庫的用法。
Lambda的語法
所謂lambda是一份功能定義式,可被定義于語句(statement)或表達式(expression)內(nèi)部。因此你可以拿lambda當作inline函數(shù)使用。
最小型的lambda函數(shù)沒有參數(shù),什么也不做,如下:
[]{std::cout<< "hello lambda" <<std::endl; }可以直接調(diào)用它:
[]{std::cout<<"hello lambda" <<std::endl; }(); //prints "hello lambda"或者把它傳遞給對象,使之能被調(diào)用:
auto l=[]{std::cout<<"hello lambda"<<std::endl;};l(); //prints “hello lambda”如你所見,lambda總是由一個所謂的lambda introducer引入:那是一組方括號,你可以在其內(nèi)指明一個所謂的capture,用來在lambda內(nèi)部訪問”nonstatic外部對象“。如果無需訪問外部數(shù)據(jù),這組方括號可以為空。Static對象,諸如cout,是可被使用的。
在lambda introducer 和lambda body之間,你可以指明參數(shù)或mutable,或一份異常明細(exception specification)或attribute specifier以及返回類型。所有這一切都可有可無,但如果其中一個出現(xiàn)了,參數(shù)所需的小括號就必須出現(xiàn)。 因此lambda語法也可以是:
[…] {…}
或
[…] (…)
Lambda 可以擁有參數(shù),指明于小括號內(nèi),就像任何函數(shù)一樣:
auto l=[](const std::string& s){std::cout<<s<<std::endl; }; l("hello lambda");然而,請注意,lambda不可以是template,你始終必須指明所有類型。
lambda也可以返回某物。但你不需要指明返回類型,該類型會根據(jù)返回值被推導出來。例如下面的lambda的返回類型是int:
[]{return 42; }如果一定想指明一個返回類型,可使用新式C++語法
[]() -> double{return 42; }會返回42.0
這里指明返回類型,放在實參所需要的小括號以及 字符->以后
下面是一個lambda表達式的使用用例:
auto num=[](const int & n){return n;};auto n=num(2);cout<<n<<endl;輸出結(jié)果:2
Capture(用以訪問外部作用域)
在lambda introducer(每個lambda最開始的方括號)內(nèi),你可以指明一個capture用來處理外部作用域內(nèi)未被傳遞為實參的數(shù)據(jù):
- [=]意味著外部作用域以by value方式傳遞給lambda。因此當這個lambda被定義時,你可以讀取所有可讀數(shù)據(jù),但不能改動它們。
- [&]意味著外部作用域以 by reference 方式傳遞給lambda。因此當這個lambda被定義時,你對所有數(shù)據(jù)的涂寫動作都是合法的,前提是你擁有涂寫它們的權(quán)力。
也可以個別指明lambda之內(nèi)你所訪問的每一個對象是by value或 by reference。因此你可以對訪問設限,也可以混合不同的訪問權(quán)力。例如下面這些語句:
int x=0; int y=42; auto qqq=[x,&y]{cout<<"x: "<<x<<endl;cout<<"y: "<<y<<endl;++y;} x=y=77;qqq(); qqq();cout<<"final y: "<<y<<endl;輸出結(jié)果
你也可以寫[=,&y] 取代[x,&y],意思是以by reference 方式傳遞y,其他所有實參則以by value 方式傳遞。
為了獲得passing by value 和passing by reference 混合體,你可以聲明lambda為mutable。下例中的對象都以by value 方式傳遞,但在這個lambda 所定義的函數(shù)對象內(nèi),你有權(quán)利涂寫傳入的值。
例如
int id=0; auto f=[id] () mutable{cout<<"id: "<<id<<endl;++id;}; id =42; f(); f(); f(); cout<<id<<endl;輸出結(jié)果
可以把上述lambda的行為視同下面這個function object
class{private:int id;// copy of outside idpublic:void operator(){cout<<"id: "<<id<<endl;++id;} };由于mutable的緣故,operator()被定義為一個non-const成員函數(shù),那意味著對id的涂寫是可能的。 所以,有了mutable,lambda變得stateful,即使state是以 by value方式傳遞。 如果沒有指明mutable(一般往往如此),operator()就成為一個const成員函數(shù),那么對于對象你就只能讀取,因為它們都是以值傳遞的。
總結(jié)
以上是生活随笔為你收集整理的C++sort如何使用lambda表达式对一维vector和二维vector进行排序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Leetcode1711. 大餐计数[C
- 下一篇: Leetcode1710. 卡车上的最大