STL常用算法(上)

本文介绍了C++STL中的几种常见算法,包括for_each用于遍历容器,transform用于搬运元素,find和find_if用于查找元素,以及count和count_if用于统计元素。同时涵盖了自定义数据类型和谓词的使用。
摘要由CSDN通过智能技术生成

触类旁通

常用遍历算法

for_each

功能描述:
实现遍历容器
函数原型:
for_each(iterator beg, iterator end, _func) ;
// 遍历算法 遍历容器元素
// beg 开始迭代器
// end 结束迭代器
// _func 函数或者函数对象
#include <iostream>
#include<vector>
#include<algorithm>//算法 
using namespace std;
//常用遍历算法  for_each

//普通函数
void print01(int val){
	cout<<val<<" ";
} 

//仿函数
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");
}

这里分别用两种函数类型实现,一种叫普通函数,也叫函数名        第二种叫仿函数,也叫函数对象

for_each(v.begin(),v.end(),print01);//始    末    函数名称 [这里传递的是函数指针(放函数名),不是仿函数,所以不加括号]
    //创建仿函数因为重载了(),所以要加()

注意看括号添加有无

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 v){
			return v+100;//搬运过程可以修改 
		}
};

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

 这个案例好,综合了foreach和transform算法     

与第一个for_each相同,既可以用仿函数又可以用普通函数

    vector<int>vTarget;//目标容器
    vTarget.resize(v.size());//目标容器  需要提前的开辟空间
    //搬运的目标容器必须要提前开辟空间,否则无法正常搬运  

这一块是核心,要有搬向空间和必须提前开辟空间

 常用查找算法

find

功能描述:
查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器 end()
函数原型:
find(iterator beg, iterator end, value) ;
// 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
// beg 开始迭代器
// end 结束迭代器
// value 查找的元素

#include <iostream>
#include<vector>
#include<algorithm>//算法 
#include<string>
using namespace std;
//查找  内置数据类型 
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<<"找到了"<<*it<<endl;
	}
	
} 
//查找自定义数据类型
class Person{
	public:
		Person(string name,int age)//构造函数赋初值 
		{
			this->m_Name=name;
			this->m_Age=age;
		}
		
	//自定义类型要重载 "=="   底层find知道如何对比person数据类型
	bool operator==(const Person&p)//明确该如何对待Person数据类型   如何相等 
	{
		if(this->m_Name==p.m_Name&&this->m_Age==p.m_Age){
			return true;
		}else{
			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);
	
	Person pp("bbb",20);//找个容器中看是否有一样的人 
	
	vector<Person>::iterator it=find(v.begin(),v.end(),pp);//查找p2 

	if(it==v.end()) {
		cout<<"没找到"<<endl;
	}else{
		cout<<"找到了 姓名:"<<it->m_Name<<"年龄"<<it->m_Age<<endl; 
	}
} 
int main()
{
//	test01();
	test02();
	system("pause");
}

本代码数据类型用了一个内置数据类型,一个自定义

    自定义类型要重载 "=="   底层find知道如何对比person数据类型

因为自定义类型不同于内置类型,用本代码为例,数据类型为Person p1("aaa",10);

以下是明确类型    
    bool operator==(const Person&p)//明确该如何对待Person数据类型   如何相等 
    {
        if(this->m_Name==p.m_Name&&this->m_Age==p.m_Age){
            return true;
        }else{
            return false;
        }
    }

find_if

功能描述:
按条件查找元素
函数原型:
find_if(iterator beg, iterator end, _Pred) ;
// 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
// beg 开始迭代器
// end 结束迭代器
// _Pred 函数或者谓词(返回bool类型的仿函数)这个是主要的
代码和上一个类似                结果为这样
我想让这个输出可以得出所有比5大的数
我的想法是这样的
int p=it;//先把这个p记录下来,然后后面每次用这个p当首位置进行遍历到end;
发现for_each(p,it->end(),print01);//遍历输出
但发现报错,第一个不能是普通函数,要是迭代器.
然后尝试将p类型设置为vector<int>p;然后发现还是报错,思考后是不是想复杂了,
加上了
void print01(int val){
    cout<<val<<" ";
for_each(v.begin()=it,v.end(),print01);

 程序正常输出成功。所以要多思考,暂停一下也行.

#include <iostream>
#include<vector>
#include<algorithm>//算法 

using namespace std;
void print01(int val){
	cout<<val<<" ";
} 
//1 查找内置数据类型 
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<<"找到了大于5的数字为"<<*it<<endl;
	}
	for_each(v.begin()=it,v.end(),print01);
	
} 

//2 查找自定义数据类型
void test02(){
	
} 
int main()
{
	test01();
	system("pause");
}

是我预期的效果 ok

然后将其修改为自定义数据类型

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





//2 查找自定义数据类型
class Person{
	public:
		Person(string name,int age){
			this->m_Name=name;
			this->m_Age=age;	
		}
	string m_Name;
	int m_Age;
};

//谓词
class Greater20{
	public:
		bool operator()(Person &p){
			return p.m_Age>20;
		}
}; 
//void print02(Person val){
//	cout<<val.m_Age<<val.m_Name<<" "<<endl;
//	
//} 
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);
	
	//找年龄大于20的人
	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;
	 }
	 
//	 for_each(v.begin()=it,v.end(),print02);
} 
int main()
{
//	test01();
	test02();
	system("pause");
}

然后我想是不是也可以在这也加几行代码,实现效果和上一个相同,都可输出多个结果

经过了多次实验和思考,最后得出了代码

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





//2 查找自定义数据类型
class Person{
	public:
		Person(string name,int age){
			this->m_Name=name;
			this->m_Age=age;	
		}
	string m_Name;
	int m_Age;
};

//谓词
class Greater20{
	public:
		bool operator()(Person &p){
			return p.m_Age>20;
		}
}; 
void print02(Person val){
	cout<<val.m_Age<<val.m_Name<<" "<<endl;
	
} 
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);
	
	//找年龄大于20的人
	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;
	 }
	 
	 for_each(v.begin()=it,v.end(),print02);
} 
int main()
{
//	test01();
	test02();
	system("pause");
}

adjacent_find

功能描述:
查找相邻重复元素        stl面试会用
函数原型:
adjacent_find(iterator beg, iterator end) ;
// 查找 相邻重复元素 , 返回相邻元素的第一个位置的迭代器
// beg 开始迭代器
// end 结束迭代器

vector<int>::iterator pos=adjacent_find(v.begin(),v.end());//返回迭代器的位置  

特点,其每个算法基本都返回迭代器了

代码如下

#include <iostream>
#include<vector>
#include<algorithm>//算法 
//相邻且重复才满足 
using namespace std;
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");
}

 binary_search

这个就和上面的有所不同了,上面的是查到了返回迭代器,查不到也返回迭代器。但binary_search返回的是真或假,是bool类型,告诉这个元素是否存在

    //查找容器中是否有9元素
    bool ret= binary_search(v.begin(),v.end(),9);

返回是bool类型

功能描述:
查找指定元素是否存在
函数原型:
bool binary_search(iterator beg, iterator end, value) ;
// 查找指定的元素,查到 返回 true 否则 false
// 注意 : 在无序序列中不可用
// beg 开始迭代器
// end 结束迭代器
// value 查找的元素

#include <iostream>
#include<vector>
#include<algorithm>//算法 

using namespace std;
void test01(){
	vector<int>v;
	for(int i=0;i<10;i++){
		v.push_back(i);
	}
	//查找容器中是否有9元素
	bool ret= binary_search(v.begin(),v.end(),9);
	if(ret){
		cout<<"找到了元素"<<endl;
	}
	else{
		cout<<"未找到"<<endl;
	}
} 
int main()
{
	test01();
	system("pause");
}

count

功能描述:
统计元素个数
函数原型:
count(iterator beg, iterator end, value) ;
// 统计元素出现次数
// beg 开始迭代器
// end 结束迭代器
// value 统计的元素

统计内置的数据类型 

#include <iostream>
#include<vector>
#include<algorithm>//算法 头文件
using namespace std;
//1.统计内置数据类型
void test01(){
	vector<int>v;
	v.push_back(10);
	v.push_back(20);
	v.push_back(40);
	v.push_back(30);
	v.push_back(20);
	v.push_back(40);
	
	int num=count(v.begin(),v.end(),40);
	cout<<"40的元素个数为:"<<num<<endl;
}

int main()
{
	test01();
	system("pause");
}

 统计自定义数据类型

#include <iostream>
#include<vector>
#include<algorithm>//算法 头文件
#include<string>
using namespace std;
//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("曹操",40);
	//将人员插入在容器中
	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<<endl;
}
int main()
{
//	test01();
	test02();
	system("pause");
}

count_if

功能描述:
按条件统计元素个数
函数原型:
count_if(iterator beg, iterator end, _Pred) ;
// 按条件统计元素出现次数
// beg 开始迭代器
// end 结束迭代器
// _Pred 谓词                 很多算法使用函数对象来指定要进行的二元运算,或者指定谓词来确定进行特定运算。谓词是一个返回bool类型的值的函数,因为函数对象是一种类型的对象,实现operator()()成员函数并返回bool类型的值,所以函数对象也是谓词。
谓词(返回bool类型的仿函数)
经过代码验证发现谓词不止用仿函数(函数对象)来定义,用普通函数类型定义就行,主要是返回bool类型

 内置数据类型

#include <iostream>
#include<vector>
#include<algorithm>//算法 头文件

using namespace std;
//统计内置数据类型
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(20);
	v.push_back(40);
	v.push_back(20);
	
	int num=count_if(v.begin(),v.end(),Greater20());//谓词
//	很多算法使用函数对象来指定要进行的二元运算,或者指定谓词来确定进行特定运算。谓词是一个返回bool类型的值的函数,
//	因为函数对象是一种类型的对象,实现operator()()成员函数并返回bool类型的值,所以函数对象也是谓词。
	cout<<"大于20的元素个数为"<<num<<endl;
	 
} 
int main()
{
	test01();
	system("pause");
}

自定义数据类型

#include <iostream>
#include<vector>
#include<algorithm>//算法 头文件
//统计自定义数据类型
class Person{
	public:
		Person(string name,int age){
			this->m_Name=name;
			this->m_Age=age;
		}
		string m_Name;
		int m_Age;
};

class AgeGreater20{
	public:
//		谓词(返回bool类型的仿函数)
		bool operator()(const Person &p){
			return p.m_Age>20;
		}
};


void test02(){
	vector<Person>v;
	Person p1("刘备",35);
	Person p2("关羽",35);
	Person p3("张飞",35);
	Person p4("赵云",30);
	Person p5("曹操",20);
	//将人员插入在容器中
	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	v.push_back(p5);
	
	//统计  大于20岁人员个数
	int num=count_if(v.begin(),v.end(),AgeGreater20());//谓词 
	cout<<"大于20岁的人员个数为:"<<num<<endl;
} 
	 
 
int main()
{
	
	test02();
	system("pause");
}

  • 18
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值