【STL-常用算法】

常用算法

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

1 常用遍历算法

一 for_each //遍历容器

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

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

//函数对象
class print02
{
public:
	void operator()(int val)
	{
		cout << val << " ";
	}
};

//for_each算法基本用法
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();
	return 0;
}

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

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

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>v1;
	v1.resize(v.size());  //提前开辟空间
	transform(v.begin(), v.end(), v1.begin(), Transform());
	for_each(v1.begin(), v1.end(), Myprint());
}
int main()
{
	test01();
	return 0;
}

2 常用查找算法

一 find
  1. find(iterator beg, iterator end, value);
    // 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
    // beg 开始迭代器
    // end 结束迭代器
    // value 查找的元素

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

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

class Person
{
public:
	Person(string name, int age)
	{
		mname = name;
		mage = age;
	}
	//重载==
	bool operator==(const Person& p)
	{
		if (mname == p.mname && mage == p.mage)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	string mname;
	int mage;
};

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

	//查找容器中是否有5这个元素
	vector<int>::iterator it = find(v.begin(), v.end(),5);
	if (it == v.end())
	{
		cout << "没找到" << endl;
	}
	else
	{
		cout << "找到" << *it << 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);
	Person p10("cac", 30);

	vector<Person>::iterator it = find(v.begin(), v.end(), p10);
	if (it == v.end())
	{
		cout << "没有找到!" << endl;
	}
	else
	{
		cout << "找到姓名:" << it->mname << "年龄:" << it->mage << endl;
	}
}
int main()
{
	test01();
	test02();
	return 0;
}
find_if
  1. find_if(iterator beg, iterator end, _Pred);
    // 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
    // beg 开始迭代器
    // end 结束迭代器
    // _Pred 函数或者谓词(返回bool类型的仿函数)
#include<iostream>
#include <algorithm>
#include <vector>
#include <string>
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 + 1);
	}
	vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());
	if (it == v.end()) {
		cout << "没有找到!" << endl;
	}
	else {
		cout << "找到大于5的数字:" << *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("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;
	}
}
int main() {
	//test01();
	test02();
	system("pause");
	return 0;
}

adjacent_find

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

3 常用统计算法

count

  1. count(iterator beg, iterator end, value);
    // 统计元素出现次数
    // beg 开始迭代器
    // end 结束迭代器
    // value 统计的元素

count

  1. count_if(iterator beg, iterator end, _Pred);
    // 按条件统计元素出现次数
    // beg 开始迭代器
    // end 结束迭代器
    // _Pred 谓词

4 常用排序算法

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

sort排序

  1. sort(iterator beg, iterator end, _Pred);
    // 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
    // beg 开始迭代器
    // end 结束迭代器
    // _Pred 谓词

random_shuffle排序

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

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

void test01()
{
	srand((unsigned int)time(NULL));
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	for_each(v.begin(), v.end(),myprint());
	cout << endl;

	//打乱
	random_shuffle(v.begin(), v.end());
	for_each(v.begin(), v.end(), myprint());
	cout << endl;
}

int main()
{
	test01();
	return 0;
}
merge merge合并的两个容器必须的有序序列
  1. merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
    // 容器元素合并,并存储到另一容器中
    // 注意: 两个容器必须是有序的
    // beg1 容器1开始迭代器 // end1 容器1结束迭代器 // beg2 容器2开始迭代器 // end2 容器2结束迭代器 //
    dest 目标容器开始迭代器
void test01()
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10 ; i++)
{
v1.push_back(i);
v2.push_back(i + 1);
}
vector<int> vtarget;
//目标容器需要提前开辟空间
vtarget.resize(v1.size() + v2.size());
//合并 需要两个有序序列
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vtarget.begin());
for_each(vtarget.begin(), vtarget.end(), myPrint());
cout << endl;
}
reverse
  1. reverse(iterator beg, iterator end);
    // 反转指定范围的元素
    // beg 开始迭代器
#include<iostream>	
using namespace std;
#include<ctime>
#include<algorithm>
#include<vector>

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);
	}
	for_each(v.begin(), v.end(),myprint());
	cout << endl;

	//反转
	reverse(v.begin(), v.end());
	for_each(v.begin(), v.end(), myprint());
	cout << endl;
}

int main()
{
	test01();
	return 0;
}

5 常用拷贝和替换算法

  1. copy // 容器内指定范围的元素拷贝到另一容器中
  2. replace // 将容器内指定范围的旧元素修改为新元素
  3. replace_if // 容器内指定范围满足条件的元素替换为新元素
  4. swap // 互换两个容器的元素
copy(iterator beg, iterator end, iterator dest);
copy(v1.begin(), v1.end(), v2.begin());
replace(iterator beg, iterator end, oldvalue, newvalue);
replace(v.begin(), v.end(), 20,2000)
replace_if(iterator beg, iterator end, _pred, newvalue);
replace_if(v.begin(), v.end(), ReplaceGreater30(), 3000);
swap(container c1, container c2)
swap(v1, v2);

5 常用算术生成算法

算术生成算法属于小型算法,使用时包含的头文件为 #include numeric

  1. 计算区间内 容器元素累计总和
  2. accumulate(iterator beg, iterator end, value);
    // 计算容器元素累计总和
    // beg 开始迭代器
    // end 结束迭代器
    // value 起始值

accumulate(iterator beg, iterator end, value);

#include<iostream>
#include<vector>
#include <numeric>
#include <vector>
void test01()
{
vector<int> v;
for (int i = 0; i <= 100; i++) {
v.push_back(i);
}
int total = accumulate(v.begin(), v.end(), 0);
cout << "total = " << total << endl;
}
int main() {
test01();
system("pause");
return 0;
}

fill(iterator beg, iterator end, value);

// 向容器中填充元素
// beg 开始迭代器
// end 结束迭代器
// value 填充的值

fill(v.begin(), v.end(), 100);

6 常用集合算法

  1. set_intersection // 求两个容器的交集
  2. set_union // 求两个容器的并集
  3. set_difference // 求两个容器的差集
1 set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

// 求两个集合的交集
// 注意:两个集合必须是有序序列
// beg1 容器1开始迭代器 // end1 容器1结束迭代器 // beg2 容器2开始迭代器 // end2 容器2结束迭代器 //
dest 目标容器开始迭代器

#include <vector>
#include <algorithm>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
v2.push_back(i+5);
}
vector<int> vTarget;
//取两个里面较小的值给目标容器开辟空间
vTarget.resize(min(v1.size(), v2.size()));
//返回目标容器的最后一个元素的迭代器地址
vector<int>::iterator itEnd =
set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
for_each(vTarget.begin(), itEnd, myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}

总结:
1 求交集的两个集合必须的有序序列
2 目标容器开辟空间需要从两个容器中取小值
3 set_intersection返回值既是交集中最后一个元素的位置

2 set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
vector<int> vTarget;
//取两个容器的和给目标容器开辟空间
vTarget.resize(v1.size() + v2.size());
//返回目标容器的最后一个元素的迭代器地址
vector<int>::iterator itEnd =
set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
for_each(vTarget.begin(), itEnd, myPrint());
cout << endl;
}
3 set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
vector<int> vTarget;
//取两个里面较大的值给目标容器开辟空间
vTarget.resize( max(v1.size() , v2.size()));
//返回目标容器的最后一个元素的迭代器地址
cout << "v1与v2的差集为: " << endl;
vector<int>::iterator itEnd =
set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
for_each(vTarget.begin(), itEnd, myPrint());
cout << endl;
cout << "v2与v1的差集为: " << endl;
itEnd = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vTarget.begin());
for_each(vTarget.begin(), itEnd, myPrint());
cout << endl;
  • 20
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值