IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> STL常用算法----在B站听黑马程序员c++课程的记录 -> 正文阅读

[C++知识库]STL常用算法----在B站听黑马程序员c++课程的记录

介绍

主要有头文件<algorithm> <functional> <numeric>
<algorithm>是STL头文件最大的一个。
<numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,
<functional>定义了一些模板类。

常用的遍历算法

for_eachtransform , 需包含 <algorithm>头文件

for_each 遍历容器

  • 函数原型: for_each(iterator beg, iterator end, _func);,func是函数或函数对象都可以
  • 函数内部是for循环,遍历从起始迭代器,到结束迭代器,执行传入的函数或仿函数操作。
    //普通函数
    void print01(int val) {
    	cout << val << " ";
    }
    for_each(v.begin(), v.end(), print01);
    
    //函数对象
    class print02 {
     public:
    	void operator()(int val) {
    		cout << val << " ";
    	}
    };
    for_each(v.begin(), v.end(), print02());
    

transform 搬运容器到另一个容器中

  • 函数原型transform(iterator beg1, iterator end1, iterator beg2, _func);
    beg1是源容器开始迭代器,end1是源容器结束迭代器,beg2是目标容器开始迭代器
    _func 函数或者函数对象,在从源容器搬运到目标容器进行的操作
    class TransForm{
    public:
    	int operator()(int val){
    		return val;
    	}
    };
    vector<int>vTarget; //构建目标容器
    vTarget.resize(v.size()); // 提前开辟目标容器的空间,如果没空间的话运行会崩掉
    transform(v.begin(), v.end(), vTarget.begin(), TransForm());
    

常用查找算法

find //查找元素
find_if //按条件查找元素
adjacent_find //查找相邻重复元素
binary_search //二分查找法
count //统计元素个数
-count_if //按条件统计元素个数

find 查找指定元素

  • 函数原型:find(iterator beg, iterator end, value);,开始迭代器,结束迭代器和要查找的元素
  • 找到返回指定元素的迭代器,找不到返回结束迭代器end()
  1. 查找内置数据类型
    //查找int类型的数据
    vector<int>::iterator it = find(v.begin(), v.end(), 5);
    
  2. find底层中是for循环,遍历从起始迭代器,到结束迭代器,判断迭代器指向的值是否 =传入的value。在查找自定义数据类型时,编译器不知道如何判断自定义类型的相等,因此需要重载==运算符
    //查找自定义类型的数据,定义了Person类,有name和age两个成员变量,重载了==号
    class Person {
    public:
    	Person(string name, int age) {        //构造函数
    		this->m_Name = name;
    		this->m_Age = age;
    	}
    	bool operator==(const Person& p){	  //重载==
    		if (this->m_Name == p.m_Name && this->m_Age == p.m_Age) {
    			return true;
    		}
    		return false;
    	}
    	string m_Name;
    	int m_Age;
    };
    
    void test02() {
    	vector<Person> v;
    	//创建数据
    	Person p1("aaa", 10);
    	Person p2("bbb", 20);
    	Person p3("ccc", 30);
    	Person p4("ddd", 40);
    	//存入容器中
    	v.push_back(p1);
    	v.push_back(p2);
    	v.push_back(p3);
    	v.push_back(p4);
    	//查找
    	vector<Person>::iterator it = find(v.begin(), v.end(), p2);
    	if (it == v.end()) 
    	{
    		cout << "没有找到!" << endl;
    	}
    	else 
    	{
    		cout << "找到姓名:" << it->m_Name << " 年龄: " << it->m_Age << endl;
    	}
    }
    

find_if 按条件查找元素

  • 函数原型:find_if(iterator beg, iterator end, _Pred); 第三个参数是一个谓词,可以按照自己的条件找容器中是否有指定的数据。
  • 有则返回当前迭代器,没有返回end()
  1. 查找内置数据类型

    class GreaterFive{
    public:
    	bool operator()(int val){
    		return val > 5;
    	}
    };
    vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());
    if (it == v.end()) {
    	cout << "没有找到!" << endl;
    }
    else {
    	cout << "找到大于5的数字:" << *it << endl;
    }
    
  2. 查找自定义数据类型

    //自定义数据类型
    class Person {
    public:
    	Person(string name, int age){
    		this->m_Name = name;
    		this->m_Age = age;
    	}
    public:
    	string m_Name;
    	int m_Age;
    };
    
    class Greater20
    {
    public:
    	bool operator()(Person &p){
    		return p.m_Age > 20;
    	}
    };
    void test02() {
    	vector<Person> v;
    	//创建数据
    	Person p1("aaa", 10);
    	Person p2("bbb", 20);
    	Person p3("ccc", 30);
    	Person p4("ddd", 40);
    	v.push_back(p1);
    	v.push_back(p2);
    	v.push_back(p3);
    	v.push_back(p4);
    
    	vector<Person>::iterator it = find_if(v.begin(), v.end(), Greater20());
    	if (it == v.end()){
    		cout << "没有找到!" << endl;
    	}
    	else{
    		cout << "找到姓名:" << it->m_Name << " 年龄: " << it->m_Age << endl;
    	}
    }
    
    

adjacent_find 查找相邻重复元素

  • 函数原型: adjacent_find(iterator beg, iterator end);,开始迭代器,结束迭代器
  • 找到返回第一个位置的迭代器,找不到返回结束迭代器end()
    vector<int>::iterator it = adjacent_find(v.begin(), v.end());
    if (it == v.end()) {
    	cout << "找不到!" << endl;
    }
    else {
    	cout << "找到相邻重复元素为:" << *it << endl;
    }
    

binary_search 二分查找指定元素是否存在

  • 要求容器必须有序
  • 函数原型:bool binary_search(iterator beg, iterator end, value);
  • 查到 返回true 否则false
    bool ret = binary_search(v.begin(), v.end(),2);
    	if (ret)
    	{
    		cout << "找到了" << endl;
    	}
    	else
    	{
    		cout << "未找到" << endl;
    	}
    

count 统计元素个数

  • 函数原型:count(iterator beg, iterator end, value);
  • 返回值即为容器中value的个数,自定义数据类型需要重载==运算符。
  1. 统计内置数据类型
    int num = count(v.begin(), v.end(), 4);
    
  2. 统计自定义数据类型
    //自定义数据类型
    class Person{
    public:
    	Person(string name, int age){
    		this->m_Name = name;
    		this->m_Age = age;
    	}
    	bool operator==(const Person & p){
    		if (this->m_Age == p.m_Age)
    		{
    			return true;
    		}
    		else
    		{
    			return false;
    		}
    	}
    	string m_Name;
    	int m_Age;
    };
    
    void test02(){
    	vector<Person> v;
    
    	Person p1("刘备", 35);
    	Person p2("关羽", 35);
    	Person p3("张飞", 35);
    	Person p4("赵云", 30);
    	Person p5("曹操", 25);
    
    	v.push_back(p1);
    	v.push_back(p2);
    	v.push_back(p3);
    	v.push_back(p4);
    	v.push_back(p5);
        Person p("诸葛亮",35);
    	int num = count(v.begin(), v.end(), p);
    	cout << "num = " << num << endl;
    }
    

count_if 按条件统计元素个数

  • 函数原型:count_if(iterator beg, iterator end, _Pred); _Pred谓词用来指定统计规则
  • 自定义数据类型不需要重载,和正常的一样
  1. 统计内置数据类型
    class Greater4{
    public:
    	bool operator()(int val){
    		return val >= 4;
    	}
    };
    
    int num = count_if(v.begin(), v.end(), Greater4());
    
  2. 统计自定义数据类型
    class AgeLess35{
    public:
    	bool operator()(const Person &p){
    		return p.m_Age < 35;
    	}
    };
    int num = count_if(v.begin(), v.end(), AgeLess35());
    

常用排序算法

sort //对容器内元素进行排序
random_shuffle //洗牌 指定范围内的元素随机调整次序
merge // 容器元素合并,并存储到另一容器中
reverse // 反转指定范围的元素

sort 容器内元素进行排序

  • 函数原型:sort(iterator beg, iterator end, _Pred);

  • _Pred谓词用来指定统计规则,默认为升序。

  • 若要更改为降序,可以自己写函数或函数对象,也可以调用内建函数对象greater<int>(),需包含头文件#include <functional>

    //sort默认从小到大排序
    	sort(v.begin(), v.end());
    //从大到小排序,使用内建函数对象
    	sort(v.begin(), v.end(), greater<int>());
    

random_shuffle 指定范围内的元素随机调整次序

  • 函数原型: random_shuffle(iterator beg, iterator end);
  • 可以加随机种子srand,让他真实的打乱
    #include <ctime>
    srand((unsigned int)time(NULL));
    
    random_shuffle(v.begin(), v.end());
    

merge 两个容器元素合并,并存储到另一容器中

  • 函数原型:merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest); dest是目标容器开始迭代器。

  • 两个容器必须是有序的 ,合并之后也是有序的。

  • 目标容器需要提前开辟空间

    	//提前准备了v1,v2两个容器和内容
    	vector<int> vtarget;
    	//目标容器需要提前开辟空间
    	vtarget.resize(v1.size() + v2.size());
    	//合并  需要两个有序序列
    	merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vtarget.begin());
    

reverse 容器内元素反转

  • 函数原型: reverse(iterator beg, iterator end);
    reverse(v.begin(), v.end());
    

常用拷贝和替换算法

copy // 容器内指定范围的元素拷贝到另一容器中
replace // 将容器内指定范围的旧元素修改为新元素
replace_if // 容器内指定范围满足条件的元素替换为新元素
swap // 互换两个容器的元素

copy 指定范围的元素拷贝到另一容器中

  • 函数原型:copy(iterator beg, iterator end, iterator dest); dest); 为目标容器的起始迭代器
  • 目标容器需要提前分配空间
    	vector<int> v2;
    	v2.resize(v1.size());
    	copy(v1.begin(), v1.end(), v2.begin());
    

replace 指定范围的旧元素修改为新元素

  • 函数原型: replace(iterator beg, iterator end, oldvalue, newvalue);
  • 使用:replace(v.begin(), v.end(), 20,2000);

replace_if 将区间内满足条件的元素,替换成指定元素

  • 函数原型: replace_if(iterator beg, iterator end, _pred, newvalue); _pred谓词指定条件

    //大于等于30的替换为3000
    class ReplaceGreater30{
    public:
    	bool operator()(int val){
    		return val >= 30;
    	}
    };
    
    replace_if(v.begin(), v.end(), ReplaceGreater30(), 3000);
    

swap 互换两个容器的元素

  • 函数原型:swap(container c1, container c2);,两种容器需要同种类型。
  • 使用: swap(v1, v2);

常用算术生成算法

小型算法,需包含头文件#include <numeric>
accumulate // 计算容器元素累计总和
fill // 向容器中添加元素

accumulate 容器元素累计总和

  • 函数原型 accumulate(iterator beg, iterator end, value); value指起始的累加值。
  • 使用: int total = accumulate(v.begin(), v.end(), 0);

fill 向容器中填充指定的元素

  • 函数原型: fill(iterator beg, iterator end, value);
  • 使用: fill(v.begin(), v.end(), 100);

常用集合算法

set_intersection // 求两个容器的交集
set_union // 求两个容器的并集
set_difference // 求两个容器的差集

set_intersection 容器的交集

  • 函数原型: set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
  • dest为目标容器的起始迭代器,函数返回值为新容器的end()迭代器。
  • 两个集合必须为有序序列
  • 目标容器需提前分配空间。大小为容器可能性中最大的。eg取交集,容器最大为一个容器完全包含了另一个容器。即小的容器的大小。
  • 由于我们分配的容器空间可能偏大,因此需要使用目标容器返回的结束的迭代器。
    	//取两个里面较小的值给目标容器开辟空间
    	vTarget.resize(min(v1.size(), v2.size()));
    
    	//返回目标容器的最后一个元素的迭代器地址
    	vector<int>::iterator itEnd = 
            set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
    

并集与差集同理

并集目标容器开辟空间需要两个容器相加 vTarget.resize(v1.size() + v2.size());
差集目标容器开辟空间是两个容器中较大值 vTarget.resize( max(v1.size() , v2.size()));

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-01 11:44:21  更:2021-09-01 11:46:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 20:43:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计