CPP中的lambda表达式

文章目录

    • 语法
    • 用法1:sort排序自定义比较函数
      • 示例1
        • cmp写法:
      • 示例2
        • pair类型补充
    • 用法2:作为算法参数
    • 用法3:异步任务
    • 用法4:条件查找和删除
      • find_if用法以及和find的区别

lambda表达式是C++11开始引入的一种方便的创建匿名函数对象的方式。lambda表达式可以直接在需要使用函数的地方定义和使用,这大大提高了代码的可读性和简洁性。

语法

在C++中,lambda表达式的语法是:

[capture](parameters) -> return-type {body}

其中:

  • capture是捕获列表,用于指定值捕获或引用捕获。如果没有使用到任何外部的变量,那么捕获列表是空的
  • parameters是参数列表,和普通函数的参数列表一样
  • return-type是返回类型,可以省略,如果省略的话,编译器会根据函数体的返回语句自动推导
  • body是函数体。

总的来说,使用lambda表达式和普通函数的主要区别在于,lambda表达式可以直接在需要的地方定义和使用,而普通函数需要在使用前进行定义。同时,lambda表达式还可以捕获外部的变量

用法1:sort排序自定义比较函数

示例1

leetcode56.合并区间 lambda表达式用于自定义sort比较函数

class Solution {
public:
    vector<vector<int>>result;
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        //用lambda表达式来自定义sort
        sort(intervals.begin(),intervals.end(),[](const vector<int>&a,const vector<int>&b){return a[0]<b[0];}));
        
        //把第一个元素加进去
        result.push_back(intervals[0]);
        //开始遍历
        for(int i=1;i<intervals.size();i++){
            //完全不重叠,直接和.back()比较
            if(result.back()[1]<intervals[i][0]){
                result.push_back(intervals[i]);
            }
            else{
                //更新上个元素的右边界,左边界已经排好序了
                //这里需要取最大值,和他本身作比较
                result.back()[1]=max(intervals[i][1],result.back()[1]);
            }
        }
        return result;
    }
};

这段代码中,使用了lambda表达式作为std::sort的比较函数。

这个lambda表达式[](const vector& a, const vector& b){return a[0] < b[0];}是一个接受两个参数ab的函数对象,这两个参数都是类型为vector的引用,函数体是return a[0] < b[0];,即返回两个参数的第一个元素比较的结果。

这个lambda表达式的作用和自定义的cmp函数基本相同,都是对vector对象进行比较,只是lambda表达式的写法更简洁,没有必要单独定义一个cmp函数。

cmp写法:
class Solution {
public:
    static bool cmp(vector<int>&a,vector<int>&b){
        if(a[0]<b[0]) return true;//左边界升序排序
        return false;
    }
    vector<vector<int>>result;
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(),intervals.end(),cmp);
        //……
        
    }
};

示例2

再例如,如果我们有一个vector>,我们想按照第一个元素降序,第二个元素字典序升序排序,可以使用如下的lambda表达式:

std::vector<std::pair<int, std::string>> vec = {{1, "a"}, {2, "b"}, {1, "c"}};
std::sort(vec.begin(), vec.end(), [](const auto& a, const auto& b) {
    if(a.first != b.first) return a.first > b.first;
    return a.second < b.second;
});
pair类型补充

std::pair 是 C++ 标准库中的一个模板类,用来存放一对值。它可以在任何地方使用,不仅仅在 std::map 中。std::pair 在许多标准库容器中都有应用,例如 std::mapstd::unordered_map

std::map 中,每个元素都是一个 std::pair,其中 first 表示关键字(键),second 表示该关键字对应的值value。但是,std::pair 的用途更加广泛,可以用来返回两个值的函数,或者表示只有两个元素的简单数据结构

用法2:作为算法参数

许多STL算法,比如std::for_eachstd::transform等,都可以接受lambda表达式作为参数。

例如,我们有一个vector,我们想将其中的每个元素都加一,可以使用如下的lambda表达式:

std::vector<int> vec = {1, 2, 3, 4, 5};
std::for_each(vec.begin(), vec.end(), [](int& num) {
    num++;
});

用法3:异步任务

在使用std::async进行异步编程时,可以使用lambda表达式作为异步任务。’

例如,我们想异步地计算一个数的平方,可以使用如下的lambda表达式:

auto future = std::async([](int num) {
    return num * num;
}, 10);

用法4:条件查找和删除

在使用std::find_ifstd::remove_if等函数时,可以使用lambda表达式作为条件。

例如,我们有一个vector,我们想找到其中第一个偶数,可以使用如下的lambda表达式:

std::vector<int> vec = {1, 3, 5, 2, 4};
auto iter = std::find_if(vec.begin(), vec.end(), [](int num) {
    return num % 2 == 0;
});

这段代码的作用是在 vec 中查找第一个偶数。

find_if用法以及和find的区别

std::find_if 是一个算法,它遍历一个序列,查找满足某个条件的第一个元素在这里,条件是元素是偶数,这个条件由 lambda 函数 [](int num) { return num % 2 == 0; } 表示

如果 std::find_if 找到了满足条件的元素,那么它会返回一个迭代器,指向这个元素。如果没有找到满足条件的元素,那么 std::find_if 会返回 end

std::findstd::find_if区别在于它们的查找条件

std::find 查找等于给定值的元素,而 std::find_if 查找满足给定条件的元素。例如,std::find(vec.begin(), vec.end(), 2) 查找值为 2 的元素,而 std::find_if(vec.begin(), vec.end(), [](int num) { return num % 2 == 0; }) 查找偶数元素。这两个函数都返回指向找到的元素的迭代器,如果没有找到满足条件的元素,则返回 end

你可能感兴趣的:(CPP语法,容器相关与易错点记录,算法,数据结构,c++,leetcode)