欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > c/c++ >内容正文

c/c++

C++sort如何使用lambda表达式对一维vector和二维vector进行排序

发布时间:2025/4/5 c/c++ 60 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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; }

输出结果: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;} }

输出结果

3 10 1 8 5 3 20 1

下面是一些lambda表达式语法的补充。

C++11引入了lambda,允许inline函数的定义式被用作一个参数,或是一个local对象。

Lambda改变了C++标准库的用法。

Lambda的语法

所谓lambda是一份功能定义式,可被定义于语句(statement)或表达式(expression)内部。因此你可以拿lambda当作inline函数使用。

最小型的lambda函数没有参数,什么也不做,如下:

[]{std::cout<< "hello lambda" <<std::endl; }

可以直接调用它:

[]{std::cout<<"hello lambda" <<std::endl; }(); //prints "hello lambda"

或者把它传递给对象,使之能被调用:

auto l=[]{std::cout<<"hello lambda"<<std::endl;};l(); //prints “hello lambda”

如你所见,lambda总是由一个所谓的lambda introducer引入:那是一组方括号,你可以在其内指明一个所谓的capture,用来在lambda内部访问”nonstatic外部对象“。如果无需访问外部数据,这组方括号可以为空。Static对象,诸如cout,是可被使用的。

在lambda introducer 和lambda body之间,你可以指明参数或mutable,或一份异常明细(exception specification)或attribute specifier以及返回类型。所有这一切都可有可无,但如果其中一个出现了,参数所需的小括号就必须出现。 因此lambda语法也可以是:
[…] {…}


[…] (…)

Lambda 可以拥有参数,指明于小括号内,就像任何函数一样:

auto l=[](const std::string& s){std::cout<<s<<std::endl; }; l("hello lambda");

然而,请注意,lambda不可以是template,你始终必须指明所有类型。

lambda也可以返回某物。但你不需要指明返回类型,该类型会根据返回值被推导出来。例如下面的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;

输出结果:2

Capture(用以访问外部作用域)

在lambda introducer(每个lambda最开始的方括号)内,你可以指明一个capture用来处理外部作用域内未被传递为实参的数据:

  • [=]意味着外部作用域以by value方式传递给lambda。因此当这个lambda被定义时,你可以读取所有可读数据,但不能改动它们。
  • [&]意味着外部作用域以 by reference 方式传递给lambda。因此当这个lambda被定义时,你对所有数据的涂写动作都是合法的,前提是你拥有涂写它们的权力。

也可以个别指明lambda之内你所访问的每一个对象是by value或 by reference。因此你可以对访问设限,也可以混合不同的访问权力。例如下面这些语句:

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;

输出结果

你也可以写[=,&y] 取代[x,&y],意思是以by reference 方式传递y,其他所有实参则以by value 方式传递。

为了获得passing by value 和passing by reference 混合体,你可以声明lambda为mutable。下例中的对象都以by value 方式传递,但在这个lambda 所定义的函数对象内,你有权利涂写传入的值。

例如

int id=0; auto f=[id] () mutable{cout<<"id: "<<id<<endl;++id;}; id =42; f(); f(); f(); cout<<id<<endl;

输出结果

可以把上述lambda的行为视同下面这个function object

class{private:int id;// copy of outside idpublic:void operator(){cout<<"id: "<<id<<endl;++id;} };

由于mutable的缘故,operator()被定义为一个non-const成员函数,那意味着对id的涂写是可能的。 所以,有了mutable,lambda变得stateful,即使state是以 by value方式传递。 如果没有指明mutable(一般往往如此),operator()就成为一个const成员函数,那么对于对象你就只能读取,因为它们都是以值传递的。

总结

以上是生活随笔为你收集整理的C++sort如何使用lambda表达式对一维vector和二维vector进行排序的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。