常用算法
概述:
- 算法主要是由头文件 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
- 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
- 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
- 查找相邻重复元素
函数原型:
adjacent_find(iterator beg, iterator end);
// 查找相邻重复元素,返回相邻元素的第一个位置的迭代器
// beg 开始迭代器
// end 结束迭代器
3 常用统计算法
count
- count(iterator beg, iterator end, value);
// 统计元素出现次数
// beg 开始迭代器
// end 结束迭代器
// value 统计的元素
count
- count_if(iterator beg, iterator end, _Pred);
// 按条件统计元素出现次数
// beg 开始迭代器
// end 结束迭代器
// _Pred 谓词
4 常用排序算法
- sort //对容器内元素进行排序
- random_shuffle //洗牌,指定范围内随机调整次序
- merge //合并,存储到另一容器中
- reverse //反转指定的元素
sort排序
- 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合并的两个容器必须的有序序列
- 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
- 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 常用拷贝和替换算法
- copy // 容器内指定范围的元素拷贝到另一容器中
- replace // 将容器内指定范围的旧元素修改为新元素
- replace_if // 容器内指定范围满足条件的元素替换为新元素
- 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
- 计算区间内 容器元素累计总和
- 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 常用集合算法
- set_intersection // 求两个容器的交集
- set_union // 求两个容器的并集
- 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;