STL算法主要由头文件alpgorithm,functional和numeric组成。Algothrim是所有STL头文件中最大的一个,范围涉及到比较、交换、查找、遍历、复制和修改等。Numeric体积很小,只包括在几个序列上进行简单数学运算的模板函数。Functional定义了一些模板类,用以声明函数对象。
| for_each | 遍历容器(熟练掌握) |
| transform | 搬运容器到另一个容器中 |
case 1: for_each
- #include<iostream>
- #include<vector>
- #include<algorithm>
- using namespace std;
- void Print(int v)
- {
- cout << v << " ";
- }
- class Print2
- {
- public:
- void operator()(int val)
- {
- cout << val << " ";
- }
- };
- void test01()
- {
- vector<int> v1;
- for (int i = 0; i < 10; i++)
- {
- v1.push_back(i);
- }
- //利用普通函数实现遍历操作
- for_each(v1.begin(), v1.end(), Print);
- //仿函数进行操作
- for_each(v1.begin(), v1.end(), Print2());
- }
- int main()
- {
- test01();
- }
case 2:tansform
- #include<iostream>
- #include<vector>
- #include<algorithm>
- using namespace std;
- class Transform
- {
- public:
- int operator()(int v)
- {
- return v+100; //在搬运过程中可以进行一些运算
- }
- };
- class Print
- {
- public:
- void operator()(int val)
- {
- cout << val << " ";
- }
- };
- void test01()
- {
- vector<int> v1;
- for (int i = 0; i < 10; i++)
- {
- v1.push_back(i);
- }
- vector<int> vTarget;
- vTarget.resize(v1.size()); //目标容器需要提前开辟好空间
- transform(v1.begin(),v1.end(),vTarget.begin(),Transform());
- for_each(vTarget.begin(), vTarget.end(), Print());
- cout << endl;
- }
- int main()
- {
- test01();
- }
| Find | 查找元素 |
| Find_if | 按条件查找元素 |
| Adjacent_find | 查找相邻重复元素 |
| Binary_search | 二分查找 |
| Count | 统计元素个数 |
| Count_if | 按条件统计元素个数 |
查找指定元素,找到返回指定元素的迭代器,找不到则返回结束迭代器end()。
Find(iterator beg, iterator end, value);
//beg 开始迭代器
//end 结束迭代器
//value 查找的元素
利用find可以在容器中找到指定元素,返回值是迭代器。
case 1:查找内置数据类型(查找等于5的数)
- #include<iostream>
- #include<vector>
- #include<algorithm>
- using namespace std;
- void test01()
- {
- vector<int> v1;
- for (int i = 0; i < 10; i++)
- {
- v1.push_back(i);
- }
- vector<int>::iterator it=find(v1.begin(), v1.end(), 5);
- if (it == v1.end())
- {
- cout << "没有找到!" << endl;
- }
- else
- {
- cout << "找到了"<<*it << endl;
- }
- }
- int main()
- {
- test01();
- }
case 2:查找自定义数据类型
- #include<iostream>
- #include<vector>
- #include<algorithm>
- #include"string"
- using namespace std;
- class Person
- {
- public:
- Person(string name, int age)
- {
- this->m_name = name;
- this->m_age = age;
- }
- //重载==,让底层find知道如何对比person数据类型
- bool operator== (const Person& p)
- {
- 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 test01()
- {
- vector<Person> v;
- Person p1("wxq",10);
- Person p2("szw", 20);
- Person p3("czt", 30);
- Person p4("dj", 40);
-
- v.push_back(p1);
- v.push_back(p2);
- v.push_back(p3);
- v.push_back(p4);
-
- //查找
- Person pp("szw", 20);
- vector<Person>::iterator it=find(v.begin(), v.end(), pp);
- if (it == v.end())
- {
- cout << "没有找到!" << endl;
- }
- else
- {
- cout << "找到了" << (*it).m_name << ", age is " << (*it).m_age << endl;
- }
- }
- int main()
- {
- test01();
- }
按条件查找元素。
Find_if(iterator beg, iterator end, _Pred);
//按谓词查找,返回指定位置的迭代器,找不到则返回结束迭代器。
//beg 开始迭代器
//end 结束迭代器
//_Pred 函数或谓词(返回bool类型的仿函数)
case 1:查找内置数据类型
- #include<iostream>
- #include<vector>
- #include<algorithm>
- #include"string"
- using namespace std;
- class Greater
- {
- 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(),Greater());
- if (it == v.end())
- {
- cout << "没有找到!" << endl;
- }
- else
- {
- cout << "找到了大于5的数字为" << *it << endl;
- }
- }
- int main()
- {
- test01();
- }
case 2:查找自定义数据类型
- #include<iostream>
- #include<vector>
- #include<algorithm>
- #include"string"
- using namespace std;
- 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 test01()
- {
- vector<Person> v;
- Person p1("wxq", 10);
- Person p2("szw", 20);
- Person p3("czt", 30);
- Person p4("dj", 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 << "找到了大于20的人为:" << (*it).m_name << endl;
- }
- }
- int main()
- {
- test01();
- }
查找相邻重复元素,返回相邻元素的第一个位置的迭代器。
Adjacent_find(iterator beg, iterator end);
- #include<iostream>
- #include<vector>
- #include<algorithm>
- #include"string"
- using namespace std;
- void test01()
- {
- vector<int> v;
- v.push_back(0);
- v.push_back(2);
- v.push_back(0);
- v.push_back(1);
- v.push_back(1);
- 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();
- }
Bool binary_search(iterator beg, iterator end, value);
//二分查找无法查找无序序列,且仅能返回true或false。
容器必须是有序序列。如果是无序的序列,则结果是未知的。
- #include<iostream>
- #include<vector>
- #include<algorithm>
- #include"string"
- using namespace std;
- void test01()
- {
- vector<int> v;
- v.push_back(0);
- v.push_back(1);
- v.push_back(3);
- v.push_back(4);
- v.push_back(5);
- v.push_back(6);
- bool result = binary_search(v.begin(), v.end(), 5);
-
- if (!result)
- {
- cout << "未找到重复元素!" << endl;
- }
- else
- {
- cout << "找到了元素!" << endl;
- }
- }
- int main()
- {
- test01();
- }
统计元素个数,返回一个int类型。对于自定义数据类型,需要重载==号。
Count(iterator beg, iterator end, value);
case 1:统计内置数据类型
- #include<iostream>
- #include<vector>
- #include<algorithm>
- #include"string"
- using namespace std;
- void test01()
- {
- vector<int> v;
- v.push_back(10);
- v.push_back(10);
- v.push_back(20);
- v.push_back(30);
- v.push_back(40);
- v.push_back(40);
-
- int num = count(v.begin(), v.end(), 40);
- cout << num;
- }
- int main()
- {
- test01();
- }
case 2:统计自定义数据类型
- #include<iostream>
- #include<vector>
- #include<algorithm>
- #include"string"
- using namespace std;
- 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 test01()
- {
- vector<Person> v;
- Person p1("wxq", 10);
- Person p2("szw", 20);
- Person p3("czt", 30);
- Person p4("dj", 20);
-
- v.push_back(p1);
- v.push_back(p2);
- v.push_back(p3);
- v.push_back(p4);
- Person pp("xl", 20); //查找和XL相同岁数的人有几个
- int num = count(v.begin(), v.end(), pp);
- cout << "相同岁数的人有" << num << "个。" << endl;
- }
- int main()
- {
- test01();
- }
按照条件统计元素个数。条件由谓词决定。谓词通过仿函数设置。
Count_if(iterator beg, iterator end, _Pred);
case 1:内置数据类型
- #include<iostream>
- #include<vector>
- #include<algorithm>
- using namespace std;
- class Greater20
- {
- public:
- bool operator()(int v)
- {
- return v > 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());
- cout << "大于20的元素个数为:" << num << endl;
- }
- int main()
- {
- test01();
- }
case 2:自定义数据类型
- #include<iostream>
- #include<vector>
- #include<algorithm>
- #include"string"
- using namespace std;
- 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()(const Person& p)
- {
- return p.m_age > 20;
- }
- };
- void test01()
- {
- vector<Person> v;
- Person p1("wxq", 10);
- Person p2("szw", 20);
- Person p3("czt", 30);
- Person p4("dj", 20);
-
- v.push_back(p1);
- v.push_back(p2);
- v.push_back(p3);
- v.push_back(p4);
-
- int num = count_if(v.begin(), v.end(), Greater20());
- cout << "大于20岁的人数为" << num << "个。" << endl;
- }
- int main()
- {
- test01();
- }
| Sort | 对容器内元素进行排序 |
| Random_shuffle | 指定范围内元素随机调整次序(洗牌) |
| Merge | 容器元素合并,并存储到另一容器中 |
| reverse | 反转指定范围的元素 |
Sort(iterator beg, iterator end, _Pred);
//_Pred谓词,改变排序规则
Random_shuffle(iterator beg, iterator end);
Merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//合并算法(两个容器必须有序(同为升序或降序),合并之后依然有序,合并后不会消除相同元素)
//dest目标容器的开始迭代器
Reverse(interator beg, iterator end);
case 1:排序算法
- #include<iostream>
- #include<vector>
- #include<algorithm>
- #include<functional>
- using namespace std;
- void Print(int val)
- {
- cout << val << " ";
- }
- void test01()
- {
- vector<int> v;
- v.push_back(10);
- v.push_back(20);
- v.push_back(5);
- v.push_back(1);
- sort(v.begin(), v.end());
- for_each(v.begin(), v.end(), Print);
- cout << endl;
-
- //降序排列
- sort(v.begin(),v.end(),greater<int>());
- for_each(v.begin(), v.end(), Print);
- cout << endl;
- }
- int main()
- {
- test01();
- }
case 2:洗牌算法
- #include<iostream>
- #include<vector>
- #include<algorithm>
- #include<time.h>
- using namespace std;
- void Print(int val)
- {
- cout << val << " ";
- }
- void test01()
- {
- srand((unsigned int)time(NULL)); //用系统时间生成种子作为真正的随机数
- vector<int> v;
- v.push_back(1);
- v.push_back(2);
- v.push_back(5);
- v.push_back(3);
- //升序排列
- sort(v.begin(), v.end());
- for_each(v.begin(), v.end(), Print);
- cout << endl;
-
- //洗牌1次
- random_shuffle(v.begin(),v.end());
- for_each(v.begin(), v.end(), Print);
- cout << endl;
- //洗牌2次
- random_shuffle(v.begin(), v.end());
- for_each(v.begin(), v.end(), Print);
- cout << endl;
- }
- int main()
- {
- test01();
- }
case 3:合并算法(两个容器必须有序,合并之后依然有序)
- #include<iostream>
- #include<vector>
- #include<algorithm>
- using namespace std;
- void Print(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 + 1);
- }
- //目标容器,需要提前分配内存
- vector<int> Target;
- Target.resize(v1.size() + v2.size());
- merge(v1.begin(), v1.end(), v2.begin(), v2.end(), Target.begin());
- for_each(Target.begin(), Target.end(), Print);
- cout << endl;
- }
- int main()
- {
- test01();
- }
case 4:反转算法
- #include<iostream>
- #include<vector>
- #include<algorithm>
- using namespace std;
- void Print(int val)
- {
- cout << val << " ";
- }
- void test01()
- {
- vector<int> v1;
- for (int i = 0; i < 10; i++)
- {
- v1.push_back(i);
- }
- for_each(v1.begin(), v1.end(), Print);
- cout << endl;
- //反转后的代码
- reverse(v1.begin(), v1.end());
- for_each(v1.begin(), v1.end(), Print);
- cout << endl;
- }
- int main()
- {
- test01();
- }
| Copy | 容器内指定范围的元素拷贝到另一容器中 |
| Replace | 将容器内指定范围内的元素修改为新元素 |
| Replace_if | 容器内指定范围内满足条件的元素替换为新元素 |
| swap | 互换两个容器的元素 |
Copy(iterator beg, iterator end, iterator dest);
//dest目标起始迭代器
replace(iterator beg, iterator end,oldvalue, newvalue);
//将旧值替换为新值
//注意是将其中元素均为oldvalue的值替换为newvalue
Replace_if(iterator beg, iterator end, _Pred, newvalue);
//_Pred谓词,即条件
Swap(container c1, container c2);
//同种类型的容器才可以互换
case 1:copy算法
- #include<iostream>
- #include<vector>
- #include<algorithm>
- using namespace std;
- void Print(int val)
- {
- cout << val << " ";
- }
- void test01()
- {
- vector<int> v1;
- for (int i = 0; i < 10; i++)
- {
- v1.push_back(i);
- }
- vector<int> v2;
- v2.resize(v1.size());//分配内存空间
- copy(v1.begin(),v1.end(),v2.begin());
- for_each(v2.begin(), v2.end(), Print);
- cout << endl;
- }
- int main()
- {
- test01();
- }
case 2:replace算法
- #include<iostream>
- #include<vector>
- #include<algorithm>
- using namespace std;
- class MyPrint
- {
- public:
- void operator()(int val)
- {
- cout << val << " ";
- }
- };
- void test01()
- {
- vector<int> v1;
- for (int i = 0; i < 10; i++)
- {
- v1.push_back(i);
- }
-
- cout << "替换前为:" << endl;
- for_each(v1.begin(), v1.end(), MyPrint());
- cout << endl;
- replace(v1.begin(), v1.end(), 5, 50);
- cout << "5替换为50:" << endl;
- for_each(v1.begin(), v1.end(), MyPrint());
- cout << endl;
- }
- int main()
- {
- test01();
- }
case 3:replace_if算法
- #include<iostream>
- #include<vector>
- #include<algorithm>
- using namespace std;
- class MyPrint
- {
- public:
- void operator()(int val)
- {
- cout << val << " ";
- }
- };
- class Greater5
- {
- public:
- bool operator()(int val)
- {
- return val > 5;
- }
- };
- void test01()
- {
- vector<int> v1;
- for (int i = 0; i < 10; i++)
- {
- v1.push_back(i);
- }
- cout << "替换前为:" << endl;
- for_each(v1.begin(), v1.end(), MyPrint()); //使用仿函数打印
- cout << endl;
- //将大于5的替换为9
- replace_if(v1.begin(), v1.end(), Greater5(), 9);
- cout << "替换前后:" << endl;
- for_each(v1.begin(), v1.end(), MyPrint()); //使用仿函数打印
- cout << endl;
- }
- int main()
- {
- test01();
- }
case 4:swap算法
- #include<iostream>
- #include<vector>
- #include<algorithm>
- using namespace std;
- 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+100);
- }
- cout << "交换前为:" << endl;
- for_each(v1.begin(), v1.end(), MyPrint()); //使用仿函数打印
- cout << endl;
- for_each(v2.begin(), v2.end(), MyPrint());
- cout << endl;
- //交换v1和v2
- swap(v1, v2);
- cout << "交换后为:" << endl;
- for_each(v1.begin(), v1.end(), MyPrint());
- cout << endl;
- for_each(v2.begin(), v2.end(), MyPrint());
- cout << endl;
- }
- int main()
- {
- test01();
- }
算术生成算法属于小型算法,使用时需要包含头文件#include<numeric>
| Accumulate | 计算容器元素累计总和 |
| Fill | 向容器中添加元素 |
Accumulate(iterator beg, iterator end, value)
//value起始值,是一个起始的累加值
fill(iterator beg, iterator end, value);
//一般用于后期,重新填充
case 1:累加求和
- #include<iostream>
- #include<vector>
- #include<numeric>
- using namespace std;
- void test01()
- {
- vector<int> v;
- for (int i = 0; i <= 100; i++)
- {
- v.push_back(i);
- }
- int total=accumulate(v.begin(), v.end(), 0);//0表示起始累加值为0
- cout << "total=" << total << endl;
- }
- int main()
- {
- test01();
- }
case 2:填充算法
- #include<iostream>
- #include<vector>
- #include<numeric>
- #include<algorithm>
- using namespace std;
- void Print(int val)
- {
- cout << val << " ";
- }
- void test01()
- {
- vector<int> v;
- v.resize(10);
- //重新填充
- fill(v.begin(), v.end(), 100);
- for_each(v.begin(), v.end(), Print);
- cout << endl;
- }
- int main()
- {
- test01();
- }
| Set_intersection | 求两个容器的交集 |
| Set_union | 求两个容器的并集 |
| Set_difference | 求两个容器的差集 |
Set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//会返回一个迭代器,指向交集最后位置
//dest目标容器的开始迭代器
//原容器必须为有序序列
Set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//dest目标容器的开始迭代器
//原容器必须为有序序列
//会返回一个迭代器,指向交集最后位置
case 1:求交集
- #include<iostream>
- #include<vector>
- #include<algorithm>
- using namespace std;
- void Print(int val)
- {
- cout << val << " ";
- }
- void test01()
- {
- vector<int> v1;
- vector<int> v2;
- vector<int> Target;
- for (int i = 0; i < 10; i++)
- {
- v1.push_back(i);
- v2.push_back(i + 5);
- }
- //目标容器需要提前开辟空间
- //最特殊的情况为:大容器包含小容器,取小容器的空间即可
- Target.resize(min(v1.size(),v2.size()));
- vector<int>::iterator itEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), Target.begin());
- for_each(Target.begin(), itEnd, Print); //开辟的容量可能会大,所以用返回的结束迭代器
- cout << endl;
- }
- int main()
- {
- test01();
- }
case 2:求并集
- #include<iostream>
- #include<vector>
- #include<algorithm>
- using namespace std;
- void Print(int val)
- {
- cout << val << " ";
- }
- void test01()
- {
- vector<int> v1;
- vector<int> v2;
- vector<int> Target;
- for (int i = 0; i < 10; i++)
- {
- v1.push_back(i);
- v2.push_back(i + 5);
- }
- //目标容器需要提前开辟空间
- //最特殊的情况为:两个容器空间之和
- Target.resize(v1.size()+v2.size());
- vector<int>::iterator itEnd = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), Target.begin());
- for_each(Target.begin(), itEnd, Print); //开辟的容量可能会大,所以用返回的结束迭代器
- cout << endl;
- }
- int main()
- {
- test01();
- }