本文中的lambda表达式使用方式应该在目前的所有比赛中(C++11及以上)都是可以使用的,因为比较落后的蓝桥杯都更新到了C++14。
当题目做的越来越多,难度越来越大,相应的代码就会越来越长,通常在100行左右。
在行数这么多的基础上,如果要使用递归函数,或者是sort的cmp函数,就会需要在int main上面定义函数(代码写着写着往上翻,再去写),会使思维方向和代码方向并不一致。
如果要详细了解Lambda表达式先看:C++Lambda表达式,超详细的讲解,保证一遍懂_c++ lambda-CSDN博客
Lambda的捕获列表
存在捕获列表是因为Lambda只能调用全局变量,无法调用当前函数作用域的局部变量。
如果我们需要用到局部变量,那就需要在方括号中加入你需要的内容。
捕获列表即方括号“[ ]”
[=],以值的形式捕获当前函数作用域的所有局部变量
你无法修改当前的局部变量,是以只读形式传递进来的。
//一般情况下竞赛时候都定义的是全局变量,如果需要捕获局部变量直接扣个等号就行了,不需要单独去捕获。
[&],以地址的形式捕获当前函数作用域的所有局部变量
相当于正常使用。
如果你不需要所有局部变量,那你只要在捕获列表中加入你需要的局部变量的变量名,以逗号隔开即可。
包括在同一个函数作用域下,lambda函数A要调用lambda函数B也需要(A调用A这种递归用法在下面会提到)在捕获列表中加入函数名。
例
auto lc=[](int i){return i<<1;};
auto rc=[](int i){return i<<1|1;};
auto build=[lc,rc](int l,int r,int i,auto build){
if(l==r){ //lc,rc就是值捕获。如果写&lc,&rc就是地址捕获,不过我们只需要调用函数的值。
t[i]=a[l];
return;
}
int mid=l+r>>1;
build(l,mid,lc(i),build);
build(mid+1,r,rc(i),build);
t[i]=t[lc(i)]+t[rc(i)];
};build(1,n,1,build);
sort-cmp 正常写法
#include
using namespace std;
int a[10];
bool cmp(int a,int b){
return a
sort-cmp Lambda函数
#include
using namespace std;
int a[10];
int main(){
auto cmp=[](int a,int b){//在代码量大的时候,不需要跑到前面去自定义函数
return a
sort-cmp Lambda匿名函数
#include
using namespace std;
int a[10];
int main(){
sort(a+1,a+10,[](int a,int b){return a
三种写法都可以,任取其一。
但是Lambda函数无法写成递归。
递归 Lambda函数 错误写法
#include
using namespace std;
int a[10];
int main(){
a[1]=2;
a[2]=3;
a[3]=4;
a[4]=4;
auto dfs=[](int i){
cout<
他会显示编译不通过,我们只需要稍作修改,把Lambda函数自己作为参数传进去使用即可。
递归 Lambda函数 正确写法
#include
using namespace std;
int a[10];
int main(){
a[1]=2;
a[2]=3;
a[3]=4;
a[4]=4;
auto dfs=[](int i,auto dfs){
cout<
输出
注意!return语句一定要比递归语句先出现,不然lambda函数的auto无法确定当前函数类型,导致无法递归,语句报错。
很明显可以看到lambda来写递归和原本的递归,就是多了一个把自己当参数传进去的步骤。
可以先写好原来的dfs,然后加上这么一个参数就好了。
tip:Lambda表达式写在哪里都可以,并不局限在main函数里面,也可以是多组数据处理的solve函数里面。
例题:P3372 【模板】线段树 1 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
正常写法和Lambda写法各方面性能比较(在优化手段均一样的情况下)
正常写法
Lambda写法
个人评价这种用法比较适用于思考严谨,能保证自己算法每一步都精确无误的时候使用。