STL常用算法
1、遍历
1、for_each//遍历容器
for_each(iterator beg,iterator end,_func);
开始迭代器,结束迭代器,函数或者函数对象
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;void print1(int val){cout<<val<<" ";
}//函数对象
class print2{public:void operator()(int val){cout<<val<<" ";}
};//for_each用法
void test(){vector<int> v;for(int i=0;i<10;i++){v.push_back(i);}//遍历容器中的数据for_each(v.begin(),v.end(),print1);cout<<endl;for_each(v.begin(),v.end(),print2());cout<<endl;
}int main()
{test();system("pause");return 0;
}
2、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 val){return val;}
};class MyPrint{public:void operator()(int val){cout<<val<<" ";}
};void test(){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());//遍历输出
}int main()
{test();system("pause");return 0;
}
搬运的目标容器必须要提前开辟空间,否则无法正常搬运
2、查找
find //查找元素
find_if //按条件查找元素
adjacent_find //查找相邻重复元素
binary_search //二分查找
count //统计元素个数
count_if //按条件统计元素个数
1、find
find(iterator first,iterator last,value val)//按值查找,返回value的位置,找不到返回last
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;void test(){vector<int>v;for(int i=0;i<10;i++){v.push_back(i+1);}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,int sex){this->m_Name = name;this->m_Age = age;this->m_Sex = sex;}bool operator==(const Person& p){if(this->m_Name==p.m_Name&&this->m_Age==p.m_Age&&this->m_Sex==p.m_Sex){return true;}return false;}string m_Name;int m_Age;int m_Sex;
};void test2(){vector<Person>v;Person p1("Tom",18,1);Person p2("Jack",19,0);Person p3("Mary",20,1);Person p4("Jerry",21,0);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);auto it = find(v.begin(),v.end(),p2);if(it==v.end()){cout<<"未找到"<<endl;}else{cout<<"找到"<<it->m_Name<<endl;}
}int main()
{test();test2();system("pause");return 0;
}
2、find_if
只返回第一个满足条件的
find_if(iterator beg,iterator end,_Pred)
_Perd函数或谓词(返回bool类型的仿函数)
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;class GreaterFive{public:bool operator()(int val){return val>5;}
};void test(){vector<int> v;for(int i=0;i<10;i++){v.push_back(i);}auto it=find_if(v.begin(),v.end(),GreaterFive());if(it==v.end()){cout<<"没有找到大于5的元素"<<endl;}else{cout<<"找到大于5的元素:"<<*it<<endl;}
}class Person{public:Person(string name,int age){this->m_Name=name;this->m_Age=age;}string m_Name;int m_Age;
};class GreaterAge{public:bool operator()(Person &p){return p.m_Age>30;}
};void test2(){vector<Person> v;v.push_back(Person("Tom",20));v.push_back(Person("Jerry",30));v.push_back(Person("Jim",40));v.push_back(Person("Jack",50));auto it=find_if(v.begin(),v.end(),GreaterAge());if(it==v.end()){cout<<"没有找到大于30岁的人"<<endl;}else{cout<<"找到大于30岁的人:"<<it->m_Name<<endl;}
}int main()
{test();test2();system("pause");return 0;
}
3、adjacent_find
adjacent_find(iterator brg,iterator end);
// 返回相邻重复元素第一个位置的迭代器
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;void test(){vector<int> v{1,2,3,4,5,6,7,8,9,9,11,12,13,14,15,16,16,18,19,20};cout<<*adjacent_find(v.begin(),v.end())<<endl;//9
}int main()
{test();system("pause");return 0;
}
4、binary_search
bool binary_search(iterator beg,iterator end,value);
// 注意: 在无序序列中不可用
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;void test(){vector<int> v;for(int i=0;i<10;i++){v.push_back(i);}bool ret=binary_search(v.begin(),v.end(),5);if(ret){cout<<"找到了"<<endl;}else{cout<<"没找到"<<endl;}
}int main()
{test();system("pause");return 0;
}
5、count
count(iterator beg,iterator end,value)
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;void test(){vector<int> v{1,2,3,4,5,5,5,8,9,10};int num = count(v.begin(),v.end(),5);cout<<num<<endl;
}int main()
{test();system("pause");return 0;
}
6、count_if
count_if(iterator begin, iterator end, _Prep)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;class Greater4{public:bool operator()(int val){return val > 4;}
};void test(){vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};cout << count_if(v.begin(), v.end(), Greater4()) << endl;
}class Person{public:Person(string name,int age){this->m_Name = name;this->m_Age = age;}string m_Name;int m_Age;
};class Age30{public:bool operator()(const Person &p){return p.m_Age > 30;}
};void test2(){vector<Person> v;v.push_back(Person("张三", 20));v.push_back(Person("李四", 30));v.push_back(Person("王五", 40));v.push_back(Person("赵六", 50));cout << count_if(v.begin(), v.end(), Age30()) << endl;
}int main()
{test();test2();system("pause");return 0;
}
3、排序
sort // 对容器内元素进行排序
random_shuffle // 对序列进行洗牌
merge // 合并两个有序序列,并存储到另一个容器中
reverse // 翻转序列
1、 sort
sort(iterator beg,iterator end,_Prep)
//按值查找元素,返回指定位置的迭代器,找不到返回结束位置
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;void myPrint(int val){cout<<val<<" ";
}void test(){vector<int> v{10,60,20,120,50};sort(v.begin(),v.end());for_each(v.begin(),v.end(),myPrint);//遍历输出cout<<endl;
}int main()
{test();system("pause");return 0;
}
2、random_shuffle
随机洗牌
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;class myPrint{public:void operator()(int val){cout<<val<<" ";}
};void test(){vector<int> v{1,2,3,4,5,6,7,8,9,10};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()
{test();system("pause");return 0;
}
3、merge
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
两个容器元素合并,并存储到另一容器中,两个容器必须是有序的
dest 是目标容器的起始迭代器
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;class myPrint{public:void operator()(int val){cout << val << " ";}
};void test(){vector<int> v1{1, 10, 5, 7, 9};vector<int> v2{11, 20, 15, 17, 19};sort(v1.begin(), v1.end());sort(v2.begin(), v2.end());vector<int> v3;v3.resize(v1.size() + v2.size());merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin()); for_each(v3.begin(), v3.end(), myPrint());}int main()
{test();system("pause");return 0;
}
4、reverse
将容器内的元素反转,容器必须支持随机访问迭代器
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;class myPrint{public:void operator()(int val){cout << val << " ";}
};void test(){vector<int> v{10,20,40,39};for_each(v.begin(), v.end(), myPrint());reverse(v.begin(), v.end());for_each(v.begin(), v.end(), myPrint());
}
int main()
{test();system("pause");return 0;
}
4、拷贝和替换
copy //将指定范围元素拷贝到另一个容器
replace //替换指定范围的元素
replace_if //替换满足条件的元素
swap //交换两个容器
1.copy
copy(iterator beg,iterator end,iterator dest);//将beg到end区间的元素拷贝到dest容器中
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;class muPrint{public:void operator()(int v){cout << v << " ";}
};void test(){vector<int> v{1,2,3,4,5,6,7,8};vector<int> v2;v2.resize(v.size());copy(v.begin(),v.end(),v2.begin());for_each(v2.begin(),v2.end(),muPrint());cout << endl;
}int main()
{test();system("pause");return 0;
}
2、replace
replace(iterator beg,iterator end,oldvalue,newvalue);
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;class myPrint{public:void operator()(int val){cout << val << " ";}
};void test(){vector<int> v{10,20,30,40,50,60};for_each(v.begin(),v.end(),myPrint());cout << endl;replace(v.begin(),v.end(),30,3000000);for_each(v.begin(),v.end(),myPrint());cout << endl;
}
int main()
{test();system("pause");return 0;
}
3.replace_if
replace_if(iterator beg,iterator end,_Pred,newvalue);
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;class myGreater{public:bool operator()(int val){return val>40;}
};class myPrint{public:void operator()(int val){cout<<val<<" ";}
};void test(){vector<int> v{10,70,30,60,10,80};replace_if(v.begin(),v.end(),myGreater(),100);for_each(v.begin(),v.end(),myPrint());cout<<endl;
}int main()
{test();system("pause");return 0;
}
4.swap
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;
class myPrint{public:void operator()(int val) const{cout << val << " ";}
};void test(){vector<int> v1{1,2,3,4,5,6};vector<int> v2{10,20,30,40,50,60};swap(v1,v2);for_each(v1.begin(),v1.end(),myPrint());cout<<endl;for_each(v2.begin(),v2.end(),myPrint());cout<<endl;
}int main()
{test();system("pause");return 0;
}
5.算术生成算法
算术生成算法属于小型算法,使用时包含的头文件为 #include <numeric>
accumlate //计算容器内的元素的和
fill //将容器内的元素填充为指定值
generate //将容器内的元素生成为指定值
generate_n //将容器内的元素生成为指定值,生成n个元素
iota //将容器内的元素填充为指定值,填充的起始位置为0,递增为1
inner_product //计算两个容器内对应位置元素的乘积之和
partial_sum //计算前n个元素的和,n为容器内元素的个数
1.accumlate
accumlate(iterator beg,iterator end,value)
//value是累加的起始值,会直接参与最终的结果计算
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;void test(){vector<int> v{1,2,3,4,5,6,7,8,9};int sum=accumulate(v.begin(),v.end(),5);cout<<sum<<endl;//45是容器中的和再加上5
}int main()
{test();system("pause");return 0;
}
2.fill
fill(operator beg,iterator end,value);
#include <iostream>
#include <vector>
#include<numeric>
#include<algorithm>
using namespace std;class myPrint{public:void operator()(int val){cout<<val<<" ";}
};void test(){vector<int> v;v.resize(10);fill(v.begin(),v.end(),100);for_each(v.begin(),v.end(),myPrint());cout<<endl;
}int main()
{test();system("pause");return 0;
}
6.常用集合算法
1、set_intersection 求两个集合的交集
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
dest 为交集后的起始位置
两个集合必须是有序序列
返回到目标容器的最后一个地址
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;class myPrint{public:void operator()(int val){cout << val << " ";}
};void test(){vector<int> v1{1,2,3,4,5,6,7,8,9};vector<int> v2{2,4,6,8,10};//开辟较小的空间vector<int> vTarget;vTarget.resize(min(v1.size(), v2.size()));auto itEnd=set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());for_each(vTarget.begin(), itEnd, myPrint());cout << endl;
}int main()
{test();system("pause");return 0;
}
2、set_union 求两个集合的并集
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
两个集合必须是有序序列
返回到目标容器的最后一个地址
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;class myPrint{public:void operator()(int val){cout << val << " ";}
};void test(){vector<int> v1{1,2,3,4,5,6,7,8,9};vector<int> v2{11,22,33,44};vector<int> vtarget;vtarget.resize(v1.size()+v2.size());auto itEnd=set_union(v1.begin(),v1.end(),v2.begin(),v2.end(),vtarget.begin());for_each(vtarget.begin(),itEnd,myPrint());cout << endl;
}
int main()
{test();system("pause");return 0;
}
3、set_difference 求两个集合的差集
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
两个集合必须是有序序列
返回到目标容器的最后一个地址
#include <iostream>
#include <vector>
#include<algorithm>
using namespace std;
class myPrint{public:void operator()(int val){cout<<val<<" ";}
};void test(){vector<int> v1{1,2,3,4,5,6,7,8,9};vector<int> v2{2,4,6,8,10};vector<int> vtarget;vtarget.resize(max(v1.size(),v2.size()));auto itEnd=set_difference(v1.begin(),v1.end(),v2.begin(),v2.end(),vtarget.begin());for_each(vtarget.begin(),itEnd,myPrint());cout<<endl;
}int main()
{test();system("pause");return 0;
}