c++STL常用算法之遍历算法与查找算法——全面总结(附案例解析)(二十三)

这里有C++STL——全面总结详细教程(附案例解析)(持续更新中)


目录

STL- 常用算法

常用遍历算法

for_each

transform

常用查找算法

find

find_if

adjacent_find

binary_search

count

count_if


STL- 常用算法

概述:

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

常用遍历算法

学习目标:

  • 掌握常用的遍历算法

算法简介:

  • for_each //遍历容器

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

for_each

功能描述:

  • 实现遍历容器

函数原型:

  • for_each(iterator beg, iterator end, _func);
  • // 遍历算法 遍历容器元素
  • // beg 开始迭代器
  • // end 结束迭代器
  • // _func 函数或者函数对象
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

void Print01(int val){
	cout << val << endl;
}

class Print02 {
public:
	void operator()(int val) {
		cout << val << " ";
	}
};

void test01() {
	vector<int>v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	for_each(v.begin(), v.end(), Print01);
	cout << endl;

	for_each(v.begin(), v.end(), Print02());
	cout << endl;
}

int main() {
	test01();

	system("pause");
	return 0;
}

总结:for_each在实际开发中是最常用遍历算法,需要熟练掌握

transform

功能描述:

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

函数原型:

  • transform(iterator beg1, iterator end1, iterator beg2, _func);
  • //beg1 源容器开始迭代器
  • //end1 源容器结束迭代器
  • //beg2 目标容器开始迭代器
  • //_func 函数或者函数对象
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

class TransForm {
public:
	int operator()(int val){
		return val;
	}
};

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(), MyPrint());
	cout << endl;
}

int main() {
	test01();

	system("pause");
	return 0;
}

总结: 搬运的目标容器必须要提前开辟空间,否则无法正常搬运.

常用查找算法

学习目标:

  • 掌握常用的查找算法

算法简介:

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

find

功能描述:

  • 查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器end()

函数原型:

  • find(iterator beg, iterator end, value);
  • // 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
  • // beg 开始迭代器
  • // end 结束迭代器
  • // value 查找的元素
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

void test01() {
	vector<int>v;
	for (int i = 0; i < 10; i++){
		v.push_back(i);
	}

	vector<int>::iterator it = find(v.begin(), v.end(), 5);

	if (it == v.end()){
		cout << "没有找到!" << endl;
	}
	else{
		cout << "找到:" << *it << endl;
	}
}

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;
		}
		else
			return false;
	}
public:
	string m_Name;
	int m_Age;
};

void test02() {
	vector<Person>v;
	Person p1("a", 10);
	Person p3("b", 20);
	Person p4("c", 30);

	v.push_back(p1);
	v.push_back(p3);
	v.push_back(p4);

	vector<Person>::iterator pos;
	pos = find(v.begin(), v.end(), p3);
	if (pos == v.end()) {
		cout << "没找到" << endl;
	}
	else {
		cout << "找到:" << pos->m_Name << "  " << pos->m_Age << endl;
	}
}

int main() {
	test01();
	test02();
	system("pause");
	return 0;
}

总结: 利用find可以在容器中找指定的元素,返回值是迭代器
 

find_if

功能描述:

  • 按条件查找元素

函数原型:

  • find_if(iterator beg, iterator end, _Pred);
  • // 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
  • // beg 开始迭代器
  • // end 结束迭代器
  • // _Pred 函数或者谓词(返回bool类型的仿函数)
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

//内置数据类型
class GreaterFive{
public:
	bool operator()(int val){
		return val > 5;
	}
};

void test01() {
	vector<int>v;
	for (int i = 0; i < 10; i++){
		v.push_back(i);
	}

	vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());

	if (it == v.end()){
		cout << "没有找到!" << endl;
	}
	else{
		cout << "找到:" << *it << endl;
	}
}

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("a", 10);
	Person p3("b", 20);
	Person p4("c", 30);

	v.push_back(p1);
	v.push_back(p3);
	v.push_back(p4);

	vector<Person>::iterator pos;
	pos = find_if(v.begin(), v.end(),Greater20());
	if (pos == v.end()) {
		cout << "没找到" << endl;
	}
	else {
		cout << "找到:" << pos->m_Name << "  " << pos->m_Age << endl;
	}
}

int main() {
	test01();
	test02();
	system("pause");
	return 0;
}

总结:find_if按条件查找使查找更加灵活,提供的仿函数可以改变不同的策略。

adjacent_find

功能描述:

  • 查找相邻重复元素

函数原型:

  • adjacent_find(iterator beg, iterator end);
  • // 查找相邻重复元素,返回相邻元素的第一个位置的迭代器
  • // beg 开始迭代器
  • // end 结束迭代器

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

void test01() {
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(5);
	v.push_back(2);
	v.push_back(4);
	v.push_back(4);
	v.push_back(3);

	//查找相邻重复元素
	vector<int>::iterator it = adjacent_find(v.begin(), v.end());
	if (it == v.end()) {
		cout << "找不到!" << endl;
	}
	else {
		cout << "找到相邻重复元素为:" << *it << endl;
	}
}

int main() {
	test01();

	system("pause");
	return 0;
}

总结:面试题中如果出现查找相邻重复元素,记得用STL中的adjacent_find算法

功能描述:

  • 查找指定元素是否存在

函数原型:

  • bool binary_search(iterator beg, iterator end, value);
  • // 查找指定的元素,查到 返回true 否则false
  • // 注意: 在无序序列中不可用
  • // beg 开始迭代器
  • // end 结束迭代器
  • // value 查找的元素
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

void test01() {
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	bool ret = binary_search(v.begin(), v.end(), 2);
	cout << (ret ? "找到了" : "没找到") << endl;
}

int main() {
	test01();

	system("pause");
	return 0;
}

总结:二分查找法查找效率很高,值得注意的是查找的容器中元素必须的有序序列

count

功能描述:

  • 统计元素个数

函数原型:

  • count(iterator beg, iterator end, value);
  • // 统计元素出现次数
  • // beg 开始迭代器
  • // end 结束迭代器
  • // value 统计的元素
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

//内置数据类型
void test01(){
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(4);
	v.push_back(5);
	v.push_back(3);
	v.push_back(4);
	v.push_back(4);
	int num = count(v.begin(), v.end(), 4);
	cout << "4的个数为: " << num << endl;
}

//自定义数据类型
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;
}

int main() {
	test01();
	test02();

	system("pause");
	return 0;
}

总结: 统计自定义数据类型时候,需要配合重载 operator==

count_if

功能描述:

  • 按条件统计元素个数

函数原型:

  • count_if(iterator beg, iterator end, _Pred);
  • // 按条件统计元素出现次数
  • // beg 开始迭代器
  • // end 结束迭代器
  • // _Pred 谓词
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

class Greater4 {
public:
	bool operator()(int val) {
		return val >= 4;
	}
};

//内置数据类型
void test01(){
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(4);
	v.push_back(5);
	v.push_back(3);
	v.push_back(4);
	v.push_back(4);
	int num = count_if(v.begin(), v.end(), Greater4());
	cout << "大于4的个数为: " << num << endl;
}

//自定义数据类型
class Person{
public:
	Person(string name, int age){
		this->m_Name = name;
		this->m_Age = age;
	}
	string m_Name;
	int m_Age;
};
class AgeLess35{
public:
	bool operator()(const Person &p){
		return p.m_Age < 35;
	}
};

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);

	int num = count_if(v.begin(), v.end(), AgeLess35());
	cout << "num = " << num << endl;
}

int main() {
	test01();
	test02();

	system("pause");
	return 0;
}

总结:按值统计用count,按条件统计用count_if

 

发布了68 篇原创文章 · 获赞 141 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/cfl997/article/details/103291123