C++STL算法(2)

1 篇文章 0 订阅

算法概述

算法主要是由头文件algorithm、 functional、numeric组成。
algorithm :是所有STL头文件中最大的一个,其中常用的功能涉及到比较,交换,查找,遍历,复制,修改,反转,排序,合并等…
numeric :体积很小,只包括在几个序列容器上进行的简单运算的模板函数.
functional :定义了一些模板类,用以声明函数对象。

常用遍历算法

遍历算法 遍历容器元素
@param beg 开始迭代器
@param end 结束迭代器
@param _callback  函数回调或者函数对象
@return 函数对象

for_each(iterator beg, iterator end, _callback);

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

//for_each(iterator beg, iterator end, _callback);

//transform(iterator beg1, iterator end1, iterator beg2, _callbakc)
class myprint01
{
public:
	void operator()(int val)
	{
		cout<<val<<" ";
		count++;
	}
	int count;
};
class myprint:public binary_function<int,int,void>
{
public:
	void operator()(int val,int num) const
	{
		cout<<val+num<<" ";
	}
	int count;
};
void test01()
{
	vector<int> p;
	for(int i =0;i<5;i++)
		p.push_back(i);
	//for_each基本用法
	for_each(p.begin(),p.end(),[](int val){cout<<val<<" ";});
	cout<<endl;
	//for_each 可以保存内部记录
	myprint01 p1 = for_each(p.begin(),p.end(),myprint01());
	cout<<endl;
	cout<<p1.count<<endl;
	// 绑定参数
	for_each(p.begin(),p.end(),bind2nd(myprint(),100));
	cout<<endl;
}
//transform 将一个容器中的值搬运到另一个容器中
class mytransform
{
public:
	int operator()(int val)
	{
		return val;
	}
};
class mytransform02
{
public:
	int operator()(int val1,int val2)
	{
		return val1+val2;
	}
};

在这里插入图片描述

transform算法 将指定容器区间元素搬运到另一容器中
注意 : transform 不会给目标容器分配内存,所以需要我们提前分配好内存
@param beg1 源容器开始迭代器
@param end1 源容器结束迭代器
@param beg2 目标容器开始迭代器
@param _cakkback 回调函数或者函数对象
@return 返回目标容器迭代器

transform(iterator beg1, iterator end1, iterator beg2, _callbakc)

void test02()
{
	//容器1转到容器2
	vector<int> p;
	for(int i =5;i>0;i--)
		p.push_back(i);
	vector<int> p1;
	p1.resize(p.size());
	vector<int>::iterator pos = transform(p.begin(),p.end(),p1.begin(),mytransform());
	for_each(p1.begin(),p1.end(),myprint01());
	cout<<endl;
	for_each(p.begin(),p.end(),myprint01());
	cout<<endl;
	//容器12的和转到容器3
	vector<int>p3;
	p3.resize(p.size());
	vector<int>::iterator it = transform(p.begin(),p.end(),p1.begin(),p3.begin(),mytransform02());
	for_each(p3.begin(),p3.end(),myprint01());
	cout<<endl;
}

在这里插入图片描述

常用查找算法

/*
	find算法 查找元素
	@param beg 容器开始迭代器
	@param end 容器结束迭代器
	@param value 查找的元素
	@return 返回查找元素的位置
*/
find(iterator beg, iterator end, value)
/*
	find_if算法 条件查找
	@param beg 容器开始迭代器
	@param end 容器结束迭代器
	@param  callback 回调函数或者谓词(返回bool类型的函数对象)
	@return bool 查找返回true 否则false
*/
find_if(iterator beg, iterator end, _callback);

/*
	adjacent_find算法 查找相邻重复元素
	@param beg 容器开始迭代器
	@param end 容器结束迭代器
	@param  _callback 回调函数或者谓词(返回bool类型的函数对象)
	@return 返回相邻元素的第一个位置的迭代器
*/
adjacent_find(iterator beg, iterator end, _callback);
/*
	binary_search算法 二分查找法
	注意: 在无序序列中不可用
	@param beg 容器开始迭代器
	@param end 容器结束迭代器
	@param value 查找的元素
	@return bool 查找返回true 否则false
*/
//  必须是有序非递减序列 
bool binary_search(iterator beg, iterator end, value);
/*
	count算法 统计元素出现次数
	@param beg 容器开始迭代器
	@param end 容器结束迭代器
	@param  value回调函数或者谓词(返回bool类型的函数对象)
	@return int返回元素个数
*/
count(iterator beg, iterator end, value);
/*
	count算法 统计元素出现次数
	@param beg 容器开始迭代器
	@param end 容器结束迭代器
	@param  callback 回调函数或者谓词(返回bool类型的函数对象)
	@return int返回元素个数
*/
count_if(iterator beg, iterator end, _callback);

示例:

class greater01
{
public:
	bool operator()(int val)
	{
		if(val < 5)
			return true;
		return false;
	}
};
void test03()
{
	vector<int> p;
	for(int i =5;i>0;i--)
		p.push_back(i);
	for_each(p.begin(),p.end(),[](int val){cout<<val<<" ";});
	cout<<endl;
	//find 返回迭代器 未找到返回p.end()
	vector<int>::iterator  pos = find(p.begin(),p.end(),5);
	if(pos != p.end())
		cout<<*pos<<endl;
	else
	{
		cout<<"未找到"<<endl;
	}
	// 返回迭代器 未找到返回p.end()
	vector<int>::iterator  pos1 =  find_if(p.begin(),p.end(),greater01());
	cout<<*pos1<<endl;
	// 返回迭代器 查找相邻元素是否相等 
	vector<int>::iterator it = adjacent_find(p.begin(),p.end());
	if(it != p.end())
		cout<<*it<<endl;
	else
	{
		cout<<"未找到"<<endl;
	}
	vector<int> p1;
	for(int i =0;i<5;i++)
		p1.push_back(3);
	//若在有序数组(要求数组元素非递减)中查找到indx元素则真
	bool ret = binary_search(p1.begin(),p1.end(),3);
	cout<<ret<<endl; // 1 找到了
	//count count_if 都返回int if可以查找条件
	int num = count(p1.begin(),p1.end(),3); // 3的个数5个
	cout<<num<<endl;
	int num1 = count_if(p.begin(),p.end(),greater01()); // 小于5 的个数为4 
	cout<<num1<<endl;
}

在这里插入图片描述

排序算法

merge算法 容器元素合并,并存储到另一容器中
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest  目标容器开始迭代器

merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)

//merge 容器元素合并,并存储到另一容器中
	//俩个容器必须有序,同时升序降序要相同
	vector<int> p1,p2;
	for(int i =0;i<5;i++)
	{
		p1.push_back(i+5);
		p2.push_back(i*2);
	}
	vector<int> p3;
	p3.resize(p1.size()+p2.size());
	merge(p1.begin(),p1.end(),p2.begin(),p2.end(),p3.begin());
	for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
	cout<<endl;

在这里插入图片描述

sort算法 容器元素排序
@param beg 容器1开始迭代器
@param end 容器1结束迭代器
@param _callback 回调函数或者谓词(返回bool类型的函数对象)

sort(iterator beg, iterator end, _callback)

//sort排序算法 默认升序
	sort(p3.begin(),p3.end());
	for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
	cout<<endl;
	sort(p3.begin(),p3.end(),greater<int>());
	for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
	cout<<endl;

在这里插入图片描述

random_shuffle算法 对指定范围内的元素随机调整次序
@param beg 容器开始迭代器
@param end 容器结束迭代器

random_shuffle(iterator beg, iterator end)

//random_shuffle(iterator beg, iterator end) 随机排序
	//为了随机需要在主函数添加srand((unsigned int)time(NULL));
	random_shuffle(p3.begin(),p3.end());
	for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
	cout<<endl;

在这里插入图片描述

reverse算法 反转指定范围的元素
@param beg 容器开始迭代器
@param end 容器结束迭代器

reverse(iterator beg, iterator end)

//reverse(iterator beg, iterator end) 反转算法
	sort(p3.begin(),p3.end()); // 排序后升序
	reverse(p3.begin(),p3.end()); // 变为降序
	for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
	cout<<endl;

在这里插入图片描述
全部的排序算法代码:

// 常用排序算法
void test04()
{
	//merge 容器元素合并,并存储到另一容器中
	//俩个容器必须有序,同时升序降序要相同
	vector<int> p1,p2;
	for(int i =0;i<5;i++)
	{
		p1.push_back(i+5);
		p2.push_back(i*2);
	}
	vector<int> p3;
	p3.resize(p1.size()+p2.size());
	merge(p1.begin(),p1.end(),p2.begin(),p2.end(),p3.begin());
	for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
	cout<<endl;
	//sort排序算法 默认升序
	sort(p3.begin(),p3.end());
	for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
	cout<<endl;
	sort(p3.begin(),p3.end(),greater<int>());
	for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
	cout<<endl;
	//random_shuffle(iterator beg, iterator end) 随机排序
	//为了随机需要在主函数添加srand((unsigned int)time(NULL));
	random_shuffle(p3.begin(),p3.end());
	for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
	cout<<endl;
	//reverse(iterator beg, iterator end) 反转算法
	sort(p3.begin(),p3.end()); // 排序后升序
	reverse(p3.begin(),p3.end()); // 变为降序
	for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
	cout<<endl;
}

在这里插入图片描述

常见拷贝和替换算法

/*
	copy算法 将容器内指定范围的元素拷贝到另一容器中
	@param beg 容器开始迭代器
	@param end 容器结束迭代器
	@param dest 目标起始迭代器
*/
copy(iterator beg, iterator end, iterator dest)
/*
	replace算法 将容器内指定范围的旧元素修改为新元素
	@param beg 容器开始迭代器
	@param end 容器结束迭代器
	@param oldvalue 旧元素
	@param oldvalue 新元素
*/
replace(iterator beg, iterator end, oldvalue, newvalue)
/*
	replace_if算法 将容器内指定范围满足条件的元素替换为新元素
	@param beg 容器开始迭代器
	@param end 容器结束迭代器
	@param callback函数回调或者谓词(返回Bool类型的函数对象)
	@param oldvalue 新元素
*/
replace_if(iterator beg, iterator end, _callback, newvalue)
/*
	swap算法 互换两个容器的元素
	@param c1容器1
	@param c2容器2
*/
swap(container c1, container c2)

代码示例:

// 常用拷贝和替换算法
class compare
{
public:
	bool operator()(int val)
	{	if(val < 5)
			return true;
		return false;
	}
};
void test05()
{
	vector<int>p;
	for (int i = 0; i < 5; i++)
	{
		p.push_back(i);
	}
	vector<int>p1;
	p1.resize(p.size());
	//copy
	copy(p.begin(),p.end(),p1.begin());
	//for_each(p1.begin(),p1.end(),[](int val){cout<<val<<" ";});
	//直接输出 添加头文件iterator
	copy(p1.begin(),p1.end(),ostream_iterator<int>(cout," "));
	cout<<endl;

	vector<int>p2;
	for (int i = 0; i < 10; i++)
	{
		p2.push_back(i+1);
	}
	
	// 需求 把容器中的 3替换为300
	replace(p2.begin(),p2.end(),3,300);
	copy(p2.begin(),p2.end(),ostream_iterator<int>(cout," "));
	cout<<endl;
	// 小于5 的数替换为100
	replace_if(p2.begin(),p2.end(),compare(),100);
	copy(p2.begin(),p2.end(),ostream_iterator<int>(cout," "));
	cout<<endl;

	//	swap算法 互换两个容器的元素
	swap(p1,p2);
	copy(p1.begin(),p1.end(),ostream_iterator<int>(cout," "));
	cout<<endl;
	copy(p2.begin(),p2.end(),ostream_iterator<int>(cout," "));
	cout<<endl;
}

在这里插入图片描述

常用常数生成算法

使用前需要添加头文件***numeric***
很简单的使用方式需要熟练使用

/*
	accumulate算法 计算容器元素累计总和
	@param beg 容器开始迭代器
	@param end 容器结束迭代器
	@param value累加值
*/
accumulate(iterator beg, iterator end, value)
/*
	fill算法 向容器中添加元素
	@param beg 容器开始迭代器
	@param end 容器结束迭代器
	@param value t填充元素
*/
fill(iterator beg, iterator end, value)

代码示例:

// 常用算术生成
void test06()
{
	//accumulate算法 计算容器元素累计总和
	vector<int>p;
	for (int i = 0; i < 10; i++)
	{
		p.push_back(i+1);
	}
	copy(p.begin(),p.end(),ostream_iterator<int>(cout," "));
	int num = accumulate(p.begin(),p.end(),0);
	cout<<num<<endl;
	//计算出的总和再加上累加值 10 55+10 = 65
	num = accumulate(p.begin(),p.end(),10);
	cout<<num<<endl;
	//	fill算法 向容器中添加元素
	cout<<"fill填充:"<<endl;
	fill(p.begin(),p.end(),10);
	copy(p.begin(),p.end(),ostream_iterator<int>(cout," "));
	cout<<endl;
}

在这里插入图片描述

常用集合算法

基本不怎么会用到,了解即可。

/*
	set_intersection算法 求两个set集合的交集
	注意:两个集合必须是有序序列
	@param beg1 容器1开始迭代器
	@param end1 容器1结束迭代器
	@param beg2 容器2开始迭代器
	@param end2 容器2结束迭代器
	@param dest  目标容器开始迭代器
	@return 目标容器的最后一个元素的迭代器地址
*/
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
/*
	set_union算法 求两个set集合的并集
	注意:两个集合必须是有序序列
	@param beg1 容器1开始迭代器
	@param end1 容器1结束迭代器
	@param beg2 容器2开始迭代器
	@param end2 容器2结束迭代器
	@param dest  目标容器开始迭代器
	@return 目标容器的最后一个元素的迭代器地址
*/
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
/*
	set_difference算法 求两个set集合的差集
	注意:两个集合必须是有序序列
	@param beg1 容器1开始迭代器
	@param end1 容器1结束迭代器
	@param beg2 容器2开始迭代器
	@param end2 容器2结束迭代器
	@param dest  目标容器开始迭代器
	@return 目标容器的最后一个元素的迭代器地址
*/
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)

代码示例:

// 常用集合算法
void test07()
{
//set_intersection算法 求两个set集合的交集
	vector<int>p,p1;
	for(int i =0;i<5;i++)
	{
		p.push_back(i+1); // 12345
		p1.push_back(i+2); // 23456
	}
	vector<int>p2;
	//容器体积按照最坏情况即p p1 交集是其中一个集合,即p p1有可能是包容和被包容的关系 
	//俩个集合中小的那个即可
	p2.resize(min(p.size(),p1.size()));
	vector<int>::iterator pos = set_intersection(p1.begin(),p1.end(),p.begin(),p.end(),p2.begin()); // 23450
	//返回当前目标容器的最后一个元素的迭代器地址,因为容器的容量可能会大于他的元素个
	copy(p2.begin(),p2.end(),ostream_iterator<int>(cout," ")); // 23450
	cout<<endl;
	//使用迭代器POS后完美显示出元素
	copy(p2.begin(),pos,ostream_iterator<int>(cout," "));
	cout<<endl;
	//	set_union算法 求两个set集合的并集 注意:两个集合必须是有序序列
	//容器应该按照最坏情况即p1 p 没有交集,并集是俩个集合的总和
	p2.resize(p.size()+p1.size());
	vector<int>::iterator pos1 = set_union(p.begin(),p.end(),p1.begin(),p1.end(),p2.begin()); // 123456
	copy(p2.begin(),pos1,ostream_iterator<int>(cout," "));
	cout<<endl;
	//	set_difference算法 求两个set集合的差集 p-p1 = 1 p1- p = 6
	//差集 即俩个集合的不同元素,最坏没有交集,即容器要包括最大的一个集合所有元素
	p2.resize(max(p1.size(),p.size()));
	// p 差 p1 1
	vector<int>::iterator pos2 = set_difference(p.begin(),p.end(),p1.begin(),p1.end(),p2.begin());
	copy(p2.begin(),pos2,ostream_iterator<int>(cout," "));
	cout<<endl;
	// p1 差 p 6
	vector<int>::iterator pos3 = set_difference(p1.begin(),p1.end(),p.begin(),p.end(),p2.begin());
	copy(p2.begin(),pos3,ostream_iterator<int>(cout," "));
	cout<<endl;

}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值