C++ 泛型算法
2023-05-01 23:55:00 来源:哔哩哔哩
标准库并未给每个容器都定义成员函数来实现这些操作,而是定义了一组泛型算法——称他们为“算法”,因为他们实现了一些经典算法的公共接口,但是他们可以用于不同类型的元素和多种容器类型或者其他类型的序列。
(资料图片)
大多数算法都定义在头文件algorithm中,标准库还在头文件numeric中定义了一组数值泛型算法。
重排容器元素的算法
sort会重新排列输入序列的元素,他是利用元素类型的<运算符来实现排序的。(即从小到大排列)
消除重复单词
要消除重复单词,首先将vector排序,是的重复单词都相邻出现,然后使用unique的标准库算法来重排vector,再用erase完成删除操作。
unique并不会改变words的大小,他依然有五个元素,但是这些元素的顺序被改变然后相邻的重复元素被“删除”,因为这里其实并不是真的删除了元素,只是覆盖相邻的重复元素,unique返回的迭代器指向最后一个不重复元素之后的位置,此位置之后的元素依然存在,只是我们不知道他的值。
最后我们使用erase真正的删除这些重复值。
定制操作
使用sort算法时,sort默认使用元素类型<运算符,但是我们可以让他使用其他的方式运算,也就是重载sort。
在上面代码中,我们使用了boolIslonger作为第三个参数,来重载sort。此参数是一个谓词。
谓词
谓词是一个可调用的表达式,其返回结果是一个能用做条件的值。标准库算法所使用的谓词分为两类:一元谓词(意味着他只接受单一参数)和二元谓词(有两个参数)。接受谓词的算法对输入序列中的元素调用谓词。因此,元素类型必须能转换为谓词的参数类型。
接受一个二元谓词参数的sort版本用这个谓词代替sort的默认比较。这个谓词有一定的条件我们后面会说到。
lambda表达式
一个lambda表达式表示一个可调用的代码单元,我们可以将其理解为一个未命名的内联函数。和函数类似,lambda具有一个返回类型、一个参数列表和一个函数体。和函数不同,lambda可能定义再函数内部。
lambda表达式具有以下形式:
capture list(捕获列表)是一个lambda函数中所定义的局部变量的列表(通常为空)
return type、parameter list和function body和普通函数一样,分别表示返回类型、参数列表和函数体。但是和普通函数不同,lambda必须使用尾置返回来指定返回类型。
我们可以忽略参数列表和返回类型,但必须永远包含捕获列表和函数体
我们定义了一个可调用对象f,不接受参数返回42。
lambda的调用方式和普通函数的调用相同
lambda中忽略括号和参数列表等价于指定一个空参数列表。
忽略返回类型,lambda根据函数体中的代码推断出返回类型。如果函数体只是一个return,则返回类型从返回的表达式类型推断,否则为void。
向lambda传递参数
与普通函数不同lambda不能有默认实参,因此一个lambda调用的实参数目和形参数目相等。
我们编写以下的lambda完成比较长度的功能
空捕获列表表示他不使用局部变量。
参数为两个const string的引用。
返回值为布尔值。
这时我们的比较方式就是lambda表达式了。
使用捕获列表
stable_sort会以lambda表达式来进行比较
这个lambda表达式只有单一参数,且sz为它的局部变量。
下面我们设计一个程序他将字符串按长度排序,长度相同的维持字典序,并且用一个函数获取第一个满足size大于某一个值的迭代器,并且打印他们
lambda捕获和返回
当定义一个lambda时,编译器生成一个与lambda对应的新的(未命名的)类类型。我们后面会介绍这种类是如何生成的。目前我们可以这么理解,当向一个函数传递一个lambda时,同时定义了一个新类型和该类型的一个对象,传递的参数是此编译器生成的类类型的未命名对象。
值捕获和引用捕获
我们的捕获列表可以采用值捕获或者引用捕获,与参数不同,被捕获的值实在lambda创建时被拷贝而不是调用的时候。
如果我们把biggies改成以下形式
我们增加了两个参数os和c,因为ostream对象不能拷贝,所以要使用引用(或者指针)。
我们也可以从一个函数返回lambda。函数可以直接返回一个可调用对象,或者返回一个类对象,该类含有可调用对象的数据成员。如果函数返回一个lambda,则与函数不能返回同一个局部变量的引用类似,此lambda不能包含引用捕获。
隐式捕获
为了指示编译器推断捕获列表,我们可以在列表中写一个&或者=,告诉编译器采用的捕获方式,对应为引用捕获和值捕获。
例如我们可以重写find_if的lambda
这里sz为隐式的值捕获。
如果我们希望对一部分变量采用值捕获,对其他采用引用捕获,可以混合使用隐式和显式捕获
第一条为隐式捕获os,第二条为隐式捕获c,另一个显式捕获。
当我们使用混合捕获时,捕获列表的第一个必须是&或=。同时,显式捕获的变量必须使用与隐式捕获不同的方式。
可变lambda
如果我们希望改变一个被捕获的变量的值,就必须在参数列表首加上关键字mutable。
因为我们在创建lambda的时候已经初始化v1了,所以后续v1重新赋值为0,不影响返回值。同时mutable让v1可以改变。
一个引用捕获的变量是否可以修改依赖于此引用指向的是一个const还是非const。
指定lambda的返回类型
transform将容器中所有负值转换为其绝对值,三个参数代表范围和起点。transform将输入序列中每一个元素替换为可调用对象操作该元素得到的结果,即取绝对值。
本例中lambda返回参数的绝对值,lambda是单一的return语句,返回一个表达式结果,我们无需指定返回类型,因为可以根据条件运算符推断。
如果我们要用if作为函数体最好使用尾置返回类型。
和上面的transform等价。
关键词:
为你推荐
陕西两万五千吨市政桥梁完成“转身”
兰州40家A级旅游景区暂时关闭 开放时间暂定
北京丰台初步排查确诊病例密接、次密接258人 组织3万余
四川95岁战斗英雄何开仲有个心愿:想见见山东老战友
增产快!电力生产加速 能源供应偏紧将得到缓解
夏粮和早稻实现双增产 前三季度农林牧渔业增加值同比增
云南瑞丽江桥“守门员”:疫情防控不漏一人
“久病床前真孝子” 浙江男子照顾瘫痪母亲十载
黑龙江:儿童福利机构养育儿童保障标准提至1750元
山西新绛南关村民:因洪水离开家的日子
“十年磨一剑” 黑色矸石山终闻花果香
国家一级保护动物猎隼受伤 内蒙古警方送医救治
一罪犯强行脱逃下落不明 吉林省吉林监狱发布悬赏通告
涉案金额逾3000万 广西一“洗钱”团伙受审
青藏高原有雨雪天气 西南地区江南华南等地有明显降雨
湖南长沙县发现1例外省输入新冠肺炎确诊病例
青海互助:打造全国最大高原草莓种苗繁育中心
照片修复师:每修复一张照片越珍惜与亲人相处的时光
贵州率先在中国实现地质矿产勘查全过程数字化
浙江岱山通报一船沉没 2人获救11人失联
推荐内容
- 陕西两万五千吨市政桥梁完成“转身”
- 河北邯郸发生天然气泄漏事故致3人死亡
- 兰州40家A级旅游景区暂时关闭 开放时间暂定
- 湖北警方打掉两跨省“跑分”洗钱犯罪团伙
- 新冠肺炎疫情下如何保护孩子?张文宏建议设儿童专
- 海南儋州出现1例治愈后的境外输入病例复阳人员
- 男童脊柱侧弯压迫心肺 医生耗时7小时矫正
- 宁夏将开展18岁以上重点人群加强免疫接种工作
- 北京新增1例京外关联本地确诊病例 病例所在街道
- 北京丰台初步排查确诊病例密接、次密接258人 组
- 四川95岁战斗英雄何开仲有个心愿:想见见山东老战
- 增产快!电力生产加速 能源供应偏紧将得到缓解
- 夏粮和早稻实现双增产 前三季度农林牧渔业增加值
- 云南瑞丽江桥“守门员”:疫情防控不漏一人
- 宁夏吴忠核酸阳性者已确诊
- 宁夏吴忠市发现一例外省来吴核酸检测阳性人员
- “久病床前真孝子” 浙江男子照顾瘫痪母亲十载
- 内蒙古额济纳旗5名确诊病例行动轨迹:在同一饭店
- 北京疾控:近期去过这些地方的相关人员请主动报备
- 北京新增1例京外关联输入本地确诊病例
- 增强为民服务能力——做群众最盼事 解群众最难题
- 魏复盛:干一些平凡的实事
- 中缅边境畹町海关查获涉嫌走私海马干4381尾
- 黑龙江:儿童福利机构养育儿童保障标准提至1750元
- 山西新绛南关村民:因洪水离开家的日子
- “十年磨一剑” 黑色矸石山终闻花果香
- 适老化的游戏准备好了吗?电子游戏别忽视老年人
- 国家一级保护动物猎隼受伤 内蒙古警方送医救治
- 西安鄠邑发布2名密接者活动轨迹
- 宁夏吴忠发现一例外省来吴核酸检测阳性人员
- 上海籍阳性夫妻内蒙古行程涉及3个景区、1个民宿、
- 内蒙古额济纳旗启动IV级应急响应 排查出密接者197人
- 内蒙古二连浩特市两地调整为中风险地区
- 泥若二审宣判来了 知名游戏主播山泥若被判刑3年
- 河北邯郸发生天然气泄漏 3人窒息死亡
- 北京丰台报告1例甘肃来京人员新冠病毒核酸检测阳性
- 内蒙古二连浩特两个社区调整为中风险地区
- 一罪犯强行脱逃下落不明 吉林省吉林监狱发布悬赏
- 兰州6人核酸检测呈阳性 主城区局地调整为中风险区
- 涉案金额逾3000万 广西一“洗钱”团伙受审
产业
-
2023-05-01
-
2023-05-01
-
2023-05-01
-
【环球时快讯】1.43亿,再见勇士!彻底沦为溢价合同,库里施压后你被科尔放弃了
2023-05-01
-
2023-05-01
油气
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
经济
-
2022年7月,滴滴全球股份有限公司(在开曼群岛注册成立,于美国纽约证券交易所上市)被罚80 26亿元。这不仅是中国《个人信息保护法》颁布以来
-
中新网通辽10月18日电 (记者 张林虎)18日,记者从内蒙古自治区通辽市奈曼旗公安局获悉,国家一级保护动物--梅花鹿误入当地村民羊群,
-
中新网杭州10月18日电 (王题题 胡燕婕)云天收夏色,浅秋正渐浓。10月18日,浙江杭州市西湖游船有限公司推出的惠民多站点“西湖环湖游
-
中新网福州10月18日电 (记者 龙敏 王东明)福州市晋安区官方18日晚间通报,18日14时47分,晋安区岳峰镇化工路爱摩轮商业广场项目摩天
-
中新网兰州10月18日电 (闫姣 艾庆龙 吉翔)“红山白土头,黄河向西流。”不少人疑问,天下黄河向东流,为何甘肃永靖县这段黄河却向西