侯捷 C++ STL标准库和泛型编程 —— 6 算法 + 7 仿函数

news2024/11/24 7:07:01

6 算法

算法的标准样式:需要传进去两个指针

image-20230903084435290

6.1 算法源码

6.1.1 accumulate

两个版本:

  1. 元素累加init

    template <class InputIterator, class T>
    T accumulate(InputIterator first, InputIterator last, T init)
    {
    	for (; first != last; ++first)
    		init = init + *first; // 累加到init
    	return init;
    }
    
  2. 元素累运算init

    template <class InputIterator, class T, class BinaryOperation>
    T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op)
    {
    	for (; first != last; ++first)
    		init = binary_op(init, *first); // 累运算到init上
    	return init;
    }
    

    这里可以用任意的二元操作(可以是函数,也可以是仿函数)

测试:

#include <iostream>     // std::cout
#include <functional>   // std::minus
#include <numeric>      // std::accumulate

// 函数
int myfunc (int x, int y) {return x+2*y;}

// 仿函数
struct myclass {
	int operator()(int x, int y) {return x+3*y;}
} myobj;

void test_accumulate()
{
  cout << "\ntest_accumulate().......... \n";	
  int init = 100;
  int nums[] = {10,20,30};

  cout << "using default accumulate: ";
  cout << accumulate(nums,nums+3,init);  //160
  cout << '\n';

  cout << "using functional's minus: ";
  cout << accumulate(nums, nums+3, init, minus<int>()); //40
  cout << '\n';

  cout << "using custom function: ";
  cout << accumulate(nums, nums+3, init, myfunc);	//220
  cout << '\n';

  cout << "using custom object: ";
  cout << accumulate(nums, nums+3, init, myobj);	//280
  cout << '\n';
}															 
6.1.2 for_each

让范围里的所有元素都依次做同一件事情

Function 可以是函数也可以是仿函数

template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
	for (; first != last; ++first) {
		f(*first);
	}
	return f;
}

与C++11中的 range-based for statement 差不多

6.1.3 replace…
  • replace:范围内的所有等于 old_value 的,都被 new_value 取代

    template <class ForwardIterator, class T>
    void replace(ForwardIterator first, ForwardIterator last,
    	const T& old_value, const T& new_value)
    {
    	for (; first != last; ++first)
    	{
    		if (*first == old_value) *first = new_value;	
    	}
    }
    
  • replace_if:范围内所有满足 pred()true 的元素都被 new_value 取代

    template <class ForwardIterator,class Predicate, class T>
    void replace_if(ForwardIterator first, ForwardIterator last,
    	Predicate pred, const T& new_value)
    {
    	for (; first != last; ++first)
    	{
    		if (pred(*first)) *first = new_value;
    	}
    }
    
  • replace_copy:范围内的元素全部 copy 到新地方,其中所有等于 old_value 的,都被替代为 new_value

    template <class InputIterator, class OutputIterator, class T>
    OutputIterator replace_copy(InputIterator first, InputIterator last,
    	OutputIterator result, const T& old_value, const T& new_value)
    {
    	for (; first != last; ++first, ++result)
    	{
    		*result = (*first == old_value) ? new_value : *first;
    	}
    	return result;
    }
    
6.1.4 count…
  • count:在范围中计数值等于 value 的个数

    template <class InputIterator, class T>
    typename iterator_traits<InputIterator>::difference_type // 返回类型
    count (InputIterator first, InputIterator last, const T& value)
    {
    	typename iterator_traits<InputIterator>::difference_type n = 0;
    	for (; first != last; ++first)
    	{
    		if (*first == value) ++n;
    	}
    	return n;
    }
    
  • count_if:在范围中计数满足条件 pred() 的个数

    template <class InputIterator, class Predicate>
    typename iterator_traits<InputIterator>::difference_type // 返回类型
    count_if (InputIterator first, InputIterator last, Predicate pred)
    {
    	typename iterator_traits<InputIterator>::difference_type n = 0;
    	for (; first != last; ++first)
    	{
    		if (pred(*first)) ++n;
    	}
    	return n;
    }
    
  • 容器不带成员函数 count():array,vector,forward_list,deque
  • 容器自带成员函数 count():set / multiset,map / multimap,unordered_set / unordered_multiset,unordered_map / unorderd_multimap —— 所有关联式容器
6.1 5 find…
  • find:在范围内找到值等于 value 的元素

    template <class InputIterator, class T>
    InputIterator find(InputIterator first, InputIterator last, const T& value)
    {
    	while (first != last && *first != value) ++first;
    	return first;
    }
    
  • find_if:在范围内找到满足 pred() 的元素

    template <class InputIterator, class Predicate>
    InputIterator find_if(InputIterator first, InputIterator last, Predicate pred)
    {
    	while (first != last && !pred(*first)) ++first;
    	return first;
    }
    

都是循序查找,效率低

  • 容器不带成员函数 find():array,vector,forward_list,deque
  • 容器自带成员函数 find():set / multiset,map / multimap,unordered_set / unordered_multiset,unordered_map / unorderd_multimap —— 所有关联式容器
6.1.6 sort

源码复杂

测试:

// 函数
bool myfunc (int i,int j) { return (i<j); }

//仿函数
struct myclass {
  bool operator() (int i,int j) { return (i<j);}
} myobj;

// 定义向量
int myints[] = {32,71,12,45,26,80,53,33};
vector<int> myvec(myints, myints+8);          // 32 71 12 45 26 80 53 33

// 用默认的比较(operator <)
sort(myvec.begin(), myvec.begin()+4);         //(12 32 45 71)26 80 53 33

// 用自己的函数作比较
sort(myvec.begin()+4, myvec.end(), myfunc); 	// 12 32 45 71(26 33 53 80)

// 用自己的仿函数作比较
sort(myvec.begin(), myvec.end(), myobj);      //(12 26 32 33 45 53 71 80)


// 用反向迭代器 reverse iterator 和默认的比较(operator <)
sort(myvec.rbegin(), myvec.rend());           // 80 71 53 45 33 32 26 12

// 用显式默认比较(operator <)
sort(myvec.begin(), myvec.end(), less<int>()); // 12 26 32 33 45 53 71 80   

// 使用另一个比较标准(operator >)
sort(myvec.begin(), myvec.end(), greater<int>()); // 80 71 53 45 33 32 26 12     
  • 容器不带成员函数 sort():array,vector,deque,所有关联式容器(本身就排好序了)
  • 容器自带成员函数 sort():list,forward_list(只能用自带)

reverse iterator

image-20230903101250832

其中用的是 reverse_iterator —— iterator adapter

6.1.7 binary_search

二分查找是否存在目标元素(并不给予位置),使用前必须先排序;其主要使用 lower_bound() 来找到能放入 val 的最低位置,再判断该元素是否存在

template <class ForwardIterator, class T>
bool binary_search(ForwardIterator first, ForwardIterator last, const T& value)
{
	first = lower_bound(first, last, value);
	return (first != last && !(value < *first));
    // first == last 就是序列中所有元素都小于value
    // first == last 时,*first是没有值的,所以需要先检查
    // value < *first 就是序列中没有等于value的
    
}

lower_bound():用于在有序序列中查找==第一个大于等于==该值的元素(包括目标值本身),并返回一个指向该位置的迭代器

  • 如果目标值在序列中多次出现,返回第一个出现的位置
  • 如果目标值在序列中不存在,它将返回指向比目标值大的第一个元素位置,或者返回 last

upper_bound():用于在有序序列中查找==第一个大于==该值的元素(不包括目标值本身),并返回一个指向该位置的迭代器

  • 如果目标值在序列中多次出现,返回第一个大于目标值的位置
  • 如果目标值在序列中不存在,它将返回lower_bound() 一样的位置
image-20230903112748261

一样是前闭后开的原则,且他们都用的是二分查找的方法

7 仿函数

仿函数专门为算法服务,设计成一个函数/仿函数是为了能传入算法

image-20230904081042763

STL中的每个仿函数都继承了 binary_function / unary_function—— 融入到STL中

STL规定每个 Adaptable Function(之后可以改造的函数)都应该继承其中一个(因为之后 Function Adapter 将会提问)

// 一个操作数的操作,例如“!”
template <class Arg, class Result>
struct unary_function
{
	typedef Arg argument_type;
	typedef Result result_type;
};

// 两个操作数的操作,例如“+”
template <class Arg1, class Arg2, class Result>
struct binary_function
{
	typedef Arg1 first_argument_type;
	typedef Arg2 second_argument_type;
	typedef Result result_type;
};

// 理论大小都是0,实际上可能是1(如果有人继承,那就一定是0)

防函数是我们自己可能会写的,所以自己写的时候,如果想要融入STL,就要继承上面的两个之一

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1057289.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【小沐学前端】从零开始搭建一个Vue项目

文章目录 1、简介1.1 Vue 核心功能1.2 Vue API风格1.3 node环境 2、构建项目2.1 vue create2.2 vue ui2.3 vue init2.4 vite 结语 1、简介 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&am…

ESP32设备驱动-I2C-LCD1602显示屏驱动

I2C-LCD1602显示屏驱动 1、LCD1602介绍 LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。 通过前面的实例我们知道,并口方式…

游戏开发者如何能达到5万月薪?这太难了......

引言 大家好&#xff0c;我是亿元程序员&#xff0c;一位有着8年游戏行业经验的主程。 在现代世界&#xff0c;游戏开发已经成为一个备受追捧的职业选择&#xff0c;而月薪5万则是许多年轻游戏开发者的梦想。虽然这个目标可能看起来有些遥不可及&#xff0c;但通过坚定的决心…

周记之反思

9.25 这篇总结我承认&#xff0c;是在26号上午写的&#xff0c;那昨天晚上又聊天了&#xff0c;但是对比之前来说好很多了&#xff0c;所以26号上午也就是今天我起了个大早&#xff0c;然后把昨天的尾巴收了一下&#xff0c;没收完&#xff0c;先说说成果&#xff1a; 完成了…

意大利开源硬件公司【Arduino】完成2200万美元融资

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;意大利开源硬件公司【Arduino】今日宣布已完成2200万美元融资。 本轮融资总额已经达到5400万美元&#xff0c;本轮融资由CDP Venture Capital和Anzu Partners共同领投。 Arduino打算利用这笔资金在…

一款Python音频处理的利器

迷途小书童 读完需要 3分钟 速读仅需 1 分钟 当谈到音频处理和编辑时&#xff0c;PyDub 是一个非常强大且易于使用的开源库。它提供了许多功能&#xff0c;如音频剪切、合并、混音、变速、变调等。本篇带大家一起逐步了解 PyDub 的基本原理和使用方法。 安装 PyDub 非常简单。你…

“文化共传承 艺术润心灵”——江南大学国家艺术基金走向社区

2023年9月26日、28日晚19点&#xff0c;由无锡市文化广电和旅游局主办的2023年无锡市优秀民乐作品巡演在梁溪区、锡山区隆重举办&#xff0c;江南大学“山水清音”民乐团参演其中。 锡山区演出现场 《梅里春早》是由江南大学人文学院音乐系沈雷强教授领衔的国家艺术基金小型剧&…

OCTA数据集(Rose)+ OCTA-Net

ROSE: A Retinal OCT-Angiography Vessel Segmentation Dataset and New Model 目录 一、摘要 二、创新点 三、数据集 A. ROSE-1 B. ROSE-2 四、Method A. Coarse Stage: Split-based Coarse Segmentation Module&#xff08;粗分割模块&#xff09; 1. SCS模块概述&…

机器人中的数值优化(二十)——函数的光滑化技巧

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…

黑豹程序员-CSS四种样式的定义方式及冲突后的就近原则

4种样式定义 浏览器缺省设置&#xff08;即默认&#xff09;外部样式表&#xff08;引用的css&#xff09;内部样式表&#xff08;位于 标签内部&#xff09;内联样式&#xff08;在 HTML 元素内部&#xff09; 样式冲突如何解决&#xff1f; 若多重样式将层叠为一个&#x…

第一章 visual studio下载安装

一、官网下载 地址&#xff1a;https://visualstudio.microsoft.com/zh-hans/ 点击免费visual studio 二、安装 运行下载好的exe文件&#xff0c;自定义安装目录 三、选择需要的组件安装 只需要选择标记组件&#xff0c;然后点击安装 等待安装完成就行 四、重启电脑 安装完之后…

数据结构 B树 B+树 B*树 特性与规则说明 图解

文章目录 前言B树基本规则B树的数据插入&#xff08;文字描述图解&#xff09;B树数据查找B树效率分析B树的作用B树基本规则B树 与 B树对比B*树基本规则B*树 与 B树对比拓展 前言 B树基本规则 每个节点最多有m个子节点&#xff0c;其中m是一个正整数。根节点除外&#xff0c;其…

ESP32设备驱动-OLED-SSD1306(I2C)显示屏驱动

OLED-SSD1306(I2C)显示屏驱动 1、OLED介绍 OLED显示屏是指有机电激发光二极管(OrganicLight-EmittingDiode,OLED)由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一…

【LeetCode热题100】--543.二叉树的直径

543.二叉树的直径 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 首先我们知道一条路径的长度为该路径经过的节…

信创办公–基于WPS的EXCEL最佳实践系列 (数据整理复制粘贴)

信创办公–基于WPS的EXCEL最佳实践系列 &#xff08;数据整理复制粘贴&#xff09; 目录 应用背景操作步骤1、数据查找与替换2、复制或粘贴数据3、使用自动填充工具4、将数据拆分到多列5、应用数字格式 应用背景 数据的整理复制粘贴等在日常的工作中经常使用。本章内容主要学习…

[C++随想录] 优先级队列

优先级队列 基本使用题目训练 基本使用 priority_queue, 优先级队列, 又叫做双端队列, 头文件也是 <queue> 别看它叫做队列, 其实它是一个 堆 补充一下概念: 大根堆 — — 每一棵树的父节点比它的孩子都大小跟堆 — — 每一棵树的父节点比它的孩子都小 &#x1f447;&…

二极管的直流等效电路和微变等效电路

二级管的主要参数 1.IF&#xff08;最大整流的电流&#xff09; 二极管长期工作做能够通过电流的平均最大值&#xff1a;物理意义&#xff1a;功率电流值。 2.UR 二极管最高反向工作电压 需要留有裕度&#xff0c;通常能达到一半的裕度&#xff1b;UR不能等于UBR。 3.IR 未击穿…

【python海洋专题九】Cartopy画地形等深线图

【python海洋专题九】Cartopy画地形等深线图 水深图基础差不多了&#xff0c;可以换成温度、盐度等 本期加上等深线 本期内容 1&#xff1a;地形等深线 cf ax.contour(lon, lat, ele[:, :], levelsnp.linspace(-9000,-100,10),colorsgray, linestyles-,linewidths0.25, t…

C++标准模板(STL)- 类型支持 (std::size_t,std::ptrdiff_t,std::nullptr_t)

对象、引用、函数&#xff08;包括函数模板特化&#xff09;和表达式具有称为类型的性质&#xff0c;它限制了对这些实体所容许的操作&#xff0c;并给原本寻常的位序列提供了语义含义。 附加性基本类型及宏 sizeof 运算符返回的无符号整数类型 std::size_t 定义于头文件 <…

Ubuntu20配置Mysql常用操作

文章目录 版权声明ubuntu更换软件源Ubuntu设置静态ipUbuntu防火墙ubuntu安装ssh服务Ubuntu安装vmtoolsUbuntu安装mysql5.7Ubuntu安装mysql8.0Ubuntu卸载mysql 版权声明 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明&#xff0c;所有版权属于黑马程…