• 【C++编程语言】之STL常用算法之遍历 查找算法


    1.概述
    • 算法主要是由头文件 组成
    • 是所有STL头文件中最大的一个,范围涉及到比较,交换,查找,变量,复制,修改等等
    • 体积很小,只包括几个在序列上进行简单数学运算的函数模板函数
    • 定义了一些模板类,用以声明函数对象
    2.常用遍历算法

    算法简介:

    for_each 遍历容器

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

    2.1 for_each

    功能描述:实现遍历容器

    /*
    	函数原型:
    		for_each(iterator beg,iterator end,_func);
    		遍历算法 遍历容器元素
    		beg 开始迭代器
    		end 结束迭代器
    		_func函数或者函数对象
    */
    
    //普通函数
    void print01(int val) {
    	cout << val << " ";
    }
    
    //仿函数
    class print02 {
    public:
    	void opterator()(int va2){
    		cout << va2 << " ";
    	}
    };
    void test01() {
    
    	vector<int> v;
    	for (int i = 0; i < 10; i++) {
    		v.push_back(i);
    	}
    
    	for_each(v.begin(), v.end(), print01);
    	for_each(v.begin(), v.end(), print02());
    	cout << endl;
    }
    int main() {
    	test01();
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    2.1 transform

    功能描述:搬运容器到另一个容器中

    /*
    	函数原型:
    		transform(iterator beg1,iterator end1,iterator beg2,_func);
    		beg1 原容器开始迭代器
    		end1 原容器结束迭代器
    		beg2 目标容器开始迭代器
    		_func函数或者函数对象
    */
    class Transform {
    public:
    	int operator()(int v) {
    		return v;//不做任何逻辑运算
    	}
    };
    class MyPrint {
    public:
    	void operator()(int val) {
    		cout << val << " ";
    	}
    };
    void test01() {
    
    	vector<int> v;
    	for (int i = 0; i < 10; i++) {
    		v.push_back(i);
    	}
    
    	vector<int> vTarget;//目标容器
    	vTarget.resize(v.size());//目标容器需要提前开辟
    
    	transform(v.begin(), v.end(), vTarget.begin(), Transform());
    	for_each(vTarget.begin(), vTarget.end(), Transform());
    }
    int main() {
    	test01();
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    3.常用的查找算法

    算法种类

    • find 查找元素
    • find_if 按条件查找元素
    • adjacent_find 查找相邻重复元素
    • binary_search 二分查找法
    • count 统计元素个数
    • count_if 按条件统计元素个数
    3.1 find 查找元素 ---- 内置数据类型查找和自定义数据类型

    总结:

    • 利用find可以在容器中找到指定的元素,返回值是迭代器
    • 对于自定义的数据类型 有时需要重载符号
    /*
    	函数原型:
    		find(iterator beg,iterator end,value);
    		按照查找元素  找到返回指定位置迭代器,找不到返回结束迭代器
    		beg  开始迭代器
    		end  结束迭代器
    		value 查找的元素
    */
    class Person {
    public:
    	string m_Name;
    	int m_Age;
    	Person(string name, int age) {
    		this->m_Name = name;
    		this->m_Age = age;
    	}
    	//重载 == 底层find知道如何对比person的数据类型
    	bool operator==(const Person& p) {
    		if (this->m_Name == p.m_Name && this->m_Age == p.m_Age) {
    			return true;
    		}
    		return false;
    	}
    };
    //查找 内置数据类型
    void test01() {
    	vector<int> v;
    	for (int i = 0; i < 10; i++) {
    		v.push_back(i);
    	}
    
    	//查找 容器中 是否有 5 这个元素
    	vector<int>::iterator it = find(v.begin(), v.end(), 5);
    	if (it == v.end()) {
    		cout << "没有找到" << endl;
    	}
    	else {
    		cout << "找到了" << endl;
    	}
    }
    //查找 自定义数据类型
    void test02() {
    	vector<Person> v1;
    	//创建数据
    	Person p1("aaa", 10);
    	Person p2("bbb", 20);
    	Person p3("ccc", 30);
    	Person p4("ddd", 40);
    
    	v1.push_back(p1);
    	v1.push_back(p2);
    	v1.push_back(p3);
    	v1.push_back(p4);
    
    	//查找 容器中 是否有 p2 这个元素
    	vector<Person>::iterator it = find(v1.begin(), v1.end(), p2);
    	if (it == v1.end()) {//需要重载==号
    		cout << "没有找到" << endl;
    	}
    	else {
    		cout << "找到了" << endl;
    		cout << "姓名: " <<it->m_Name<<" 年龄: "<<it->m_Age << endl;
    	}
    }
    int main() {
    	test01();
    	test02();
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    3.2 find_if 按照条件查找元素
    /*
    	函数原型:
    		find_if(iterator beg,iterator end,_pred);
    		按值查找元素  找到返回指定位置迭代器,找不到返回结束迭代器
    		beg  开始迭代器
    		end  结束迭代器
    		_pred 函数或者谓词(返回bool类型的仿函数)
    */
    class Person {
    public:
    	string m_Name;
    	int m_Age;
    	Person(string name, int age) {
    		this->m_Name = name;
    		this->m_Age = age;
    	}
    	
    };
    //内置数据类型  查找大于5的数
    class GreaterFive {
    public:
    	bool operator()(int val) {
    		return val > 5;
    	}
    };
    //自定义数据类型  查找年龄大于20
    class Greater20 {
    public:
    	bool operator()(Person &p) {
    		return p.m_Age > 20;
    	}
    };
    //查找 内置数据类型
    void test01() {
    	vector<int> v;
    	for (int i = 0; i < 10; i++) {
    		v.push_back(i);
    	}
    
    	//查找 容器中 是否有 5 这个元素
    	vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());
    	if (it == v.end()) {
    		cout << "没有找到" << endl;
    	}
    	else {
    		cout << "找到大于5的数字为:  " << *it << endl;
    	}
    }
    //查找 自定义数据类型
    void test02() {
    	vector<Person> v1;
    	//创建数据
    	Person p1("aaa", 10);
    	Person p2("bbb", 20);
    	Person p3("ccc", 30);
    	Person p4("ddd", 40);
    
    	v1.push_back(p1);
    	v1.push_back(p2);
    	v1.push_back(p3);
    	v1.push_back(p4);
    
    	//查找 容器中 是否有 p2 这个元素
    	vector<Person>::iterator it = find_if(v1.begin(), v1.end(), Greater20());
    	if (it == v1.end()) {//需要重载==号
    		cout << "没有找到" << endl;
    	}
    	else {
    		cout << "找到了" << endl;
    		cout << "姓名: " <<it->m_Name<<" 年龄: "<<it->m_Age << endl;
    	}
    }
    int main() {
    	test01();
    	test02();
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    3.3 adjacent_find 查找相邻重复元素

    总结:现实情况中是非常少使用的,更多的是面试中提到

    /*
    	函数原型:
    		adjacent_find(iterator beg,iterator end);
    		查找相邻重复元素  返回相邻元素的第一个位置的迭代器   如果未找到返回 end()迭代器
    		beg  开始迭代器
    		end  结束迭代器
    		
    */
    
    //常用查找算法  adjacent_find
    void test01() {
    
    	vector<int> v;
    	v.push_back(0);
    	v.push_back(2);
    	v.push_back(0);
    	v.push_back(3);
    	v.push_back(1);
    	v.push_back(4);
    	v.push_back(3);
    	v.push_back(3);
    
    	vector<int>::iterator pos = adjacent_find(v.begin(), v.end());
    	if (pos==v.end()) {
    		cout<<"未找到相邻重复元素" << endl;
    	}
    	else {
    		cout << "找到相邻重复元素" << *pos<<endl;
    	}
    }
    
    int main() {
    	test01();
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    3.4 binary_search 查找指定元素是否存在

    功能描述:查找指定元素是否存在

    /*
    	函数原型:
    		bool binary_search(iterator end , value);
    		查找指定的元素  查到返回true 否则false
    		注意:在无序序列中不可以使用
    		beg  开始迭代器
    		end  结束迭代器
    		value 查找的元素
    */
    
    //常用查找算法  binary_search
    void test01() {
    
    	vector<int> v;
    	for (int i = 0; i < 10; i++) {
    		v.push_back(i);
    	}
    	//查找容器中是否有 9 这个元素
    	//注意:容器必须是有序的序列
    	//v.push_back(2) 如果是无序序列  结果未知
    	bool ret = binary_search(v.begin(),v.end(),9);
    	if (ret) {
    		cout << "找到元素" << endl;
    	}
    	else {
    		cout<<"未找到元素" << endl;
    	}
    }
    
    int main() {
    	test01();
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    3.5 count 统计元素个数
    /*
    	函数原型:
    		int count(iterator beg , iterator end ,value);
    		统计元素出现次数
    		beg  开始迭代器
    		end  结束迭代器
    		value 统计的元素
    */
    
    //1.统计内置数据类型
    void test01() {
    
    	vector<int> v;
    	v.push_back(10);
    	v.push_back(40);
    	v.push_back(30);
    	v.push_back(40);
    	v.push_back(20);
    	v.push_back(40);
    	
    	int num = count(v.begin(), v.end(), 40);
    	cout <<""<< num << endl;
    }
    //2.统计自定义数据类型
    class Person {
    public:
    	string m_Name;
    	int m_Age;
    	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;
    		}
    		else {
    			return false;
    		}
    	}
    };
    void test02() {
    
    	vector<Person> v;
    
    	//创建成员对象
    	Person p1("刘备", 35);
    	Person p2("曹操", 45);
    	Person p3("孙权", 30);
    	Person p4("诸葛亮", 35);
    	Person p5("司马懿", 40);
    	Person p6("鲁肃", 35);
    
    	//将人员插入到容器中
    	v.push_back(p1);
    	v.push_back(p2);
    	v.push_back(p3);
    	v.push_back(p4);
    	v.push_back(p5);
    	v.push_back(p6);
    
    	Person p("孙权", 30);
    	int num = count(v.begin(),v.end(),p);
    	cout << "和孙权相同的人员数目: " << num << endl;
    }
    int main() {
    	test01();
    	test02();
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    3.6 count_if 按照条件统计元素个数
    /*
    	函数原型:
    		int count_if(iterator beg , iterator end ,_pred);
    		按照条件统计元素出现次数
    		beg  开始迭代器
    		end  结束迭代器
    		_pred 谓词
    */
    
    //1.统计内置数据类型
    //提供谓词
    class Greater20 {
    public:
    	bool operator()(int val) {
    		return val > 20;
    	}
    };
    void test01() {
    
    	vector<int> v;
    	v.push_back(10);
    	v.push_back(40);
    	v.push_back(30);
    	v.push_back(40);
    	v.push_back(20);
    	v.push_back(40);
    	
    	int num = count_if(v.begin(), v.end(), Greater20());
    	cout <<"大于20的元素个数为:"<< num << endl;
    }
    
    //2.统计自定义数据类型
    class Person {
    public:
    	string m_Name;
    	int m_Age;
    	Person(string name,int age) {
    		this->m_Name = name;
    		this->m_Age = age;
    	}
    };
    //提供谓词
    class AgeGreater20 {
    public:
    	bool operator()(const Person& p) {
    		return p.m_Age > 20;
    	}
    };
    void test02() {
    
    	vector<Person> v;
    
    	//创建成员对象
    	Person p1("刘备", 35);
    	Person p2("曹操", 45);
    	Person p3("孙权", 30);
    	Person p4("诸葛亮", 35);
    	Person p5("司马懿", 40);
    	Person p6("鲁肃", 35);
    
    	//将人员插入到容器中
    	v.push_back(p1);
    	v.push_back(p2);
    	v.push_back(p3);
    	v.push_back(p4);
    	v.push_back(p5);
    	v.push_back(p6);
    
    	//统计 大于20岁人员个数
    	int num = count_if(v.begin(),v.end(), AgeGreater20());
    	cout << "大于二十岁的人员个数: " << num << endl;
    }
    int main() {
    	test01();
    	test02();
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
  • 相关阅读:
    基于Docker部署GeoWebCache(离线地图)
    第八章 互联网上的音频视频服务 | 计算机网络(谢希仁 第八版)
    力扣题目训练(20)
    若依前后端不分离-表单中某一列是其他几列计算的结果
    pta——递增的整数序列链表的插入,奇数值结点链表
    Django模块连接redis
    Ubuntu下怎么配置vsftpd
    海贼王大学生HTML网页制作作品 学生动漫网页设计模板下载 简单漫画网页设计成品 dreamweaver学生网站模板
    鸿蒙应用布局ArkUI【基础运用案例】
    光栅投影三维重建
  • 原文地址:https://blog.csdn.net/kaszxc/article/details/127556186