一、头文件
算法主要是由头文件<algorithm>
<functional>
<numeric>
组成。其中<algorithm>是STL中最大的一个,包含比较、交换、查找、遍历、复制、修改等操作。<numeric>体积较小,值包含几个在序列上面进行简单数学运算的模板函数。<functional>定义了一些模板类,用以声明函数对象。
二、遍历算法
2.1for_each
遍历容器,函数原型为:
for_each(iterator beg, iterator end, _func);
其中:beg是开始迭代器,end是结束迭代器,_func是函数或函数对象
示例如下:
void print1(int m)
{
cout<<m<<" ";
}
class print2
{
public:
bool operator()(int m)
{
cout<<m<<" ";
}
};
int main()
{
vector<int> arr={1,2,3,4,5};
for_each(arr.begin(),arr.end(),print1);//函数 输出1 2 3 4 5
cout<<endl;
for_each(arr.begin(),arr.end(),print2());//函数对象 输出1 2 3 4 5
return 0;
}
2.2transform
把一个容器的元素搬运到另一个容器。函数原型为:
transform(iterator beg1, iterator end1, iterator beg2, _func);
其中beg1 源容器起始迭代器,end1 源容器结束迭代器 beg2目标容器开始迭代器, _func是函数或函数对象
示例如下:
class Transform
{
public:
int operator()(int m)
{
return m;
}
};
class print2
{
public:
bool operator()(int m)
{
cout<<m<<" ";
}
};
int main()
{
vector<int> arr={1,2,3,4,5};
vector<int> target;
target.resize(arr.size());//目标容器必须提前开辟内存空间
transform(arr.begin(),arr.end(),target.begin(),Transform());
for_each(target.begin(),target.end(),print2());//函数对象 输出1 2 3 4 5
return 0;
}
三、查找算法
3.1find()
查找指定元素,找到返回指定元素的迭代器,找不到返回end()。函数原型为:
find(iterator beg, iterator end, value);
其中beg是开始迭代器,end是结束迭代器,val是要查找的元素
只有vector没有实现自己的find函数,要借助algorithm,其他常见容器都实现了自己的find()函数
示例如下:
vector<int> arr={1,2,3,4,5};
auto it=find(arr.begin(),arr.end(),4);
if(it!=arr.end())
cout<<"找到"<<endl;
3.2find_if()
按条件查找元素,函数原型为:
find_if(iterator beg, iterator end, _Pred);
其中beg是起始迭代器,end是结束迭代器,_pred是函数或函数对象
int pre1(int m)
{
return m>3;
}
class pre2{
public:
bool operator()(int m)
{
return m>4;
}
};
int main()
{
vector<int> arr={1,2,3,4,5};
auto it1=find_if(arr.begin(),arr.end(),pre1);//函数
if(it1!=arr.end())
cout<<"找到大于3的"<<endl;
auto it2=find_if(arr.begin(),arr.end(),pre2());//函数对象
if(it2!=arr.end())
cout<<"找到大于4的"<<endl;
return 0;
}
可以根据自己所需要的规则对仿函数进行修改。
3.3adjacent_find
查找相邻元素,函数原型为:
adjacent_find(iterator beg, iterator end);
其中beg是开始迭代器,end是结束迭代器。
用于查找容器中是否有相邻重复元素,返回相邻重复元素的第一个位置的迭代器
示例如下:
vector<int> arr={1,2,3,4,5};
auto it1=adjacent_find(arr.begin(),arr.end());
if(it1!=arr.end())
cout<<"找到"<<endl;
else
cout<<"没找到"<<endl;//输出没找到
vector<int> arr2={2,3,4,4,5};
auto it2=adjacent_find(arr2.begin(),arr2.end());
if(it2!=arr.end())
cout<<"找到"<<endl;//输出找到
else
cout<<"没找到"<<endl;
3.4 binary_search
查找指定元素是否存在,函数原型为:
bool binary_search(iterator beg, iterator end, value);
其中beg是开始迭代器,end是结束迭代器,val是要查找的元素
查找指定的元素,找到返回TRUE,找不到返回FALSE
示例如下:
vector<int> arr={1,2,3,4,5};
bool flag=binary_search(arr.begin(),arr.end(),4);
if(flag)
cout<<"找到"<<endl;
else
cout<<"未找到"<<endl;
binary_search()使用二分查找,故容器中的元素必须有序
3.5count
统计元素出现的次数,函数原型为:
count(iterator beg, iterator end, value);
其中beg是开始迭代器,end是结束迭代器,val是要统计的元素
示例如下:
vector<int> arr={1,4,2,3,3,5};
int num=count(arr.begin(),arr.end(),3);
cout<<"3的个数为"<<num<<endl;
3.6count_if
按条件查找元素,函数原型为:
count_if(iterator beg, iterator end, _Pred);
其中beg是开始迭代器,end是结束迭代器,_pred是函数或函数对象
返回的是符和条件的元素个数。
示例如下:
int pre1(int m)
{
return m>3;
}
class pre2{
public:
bool operator()(int m)
{
return m>4;
}
};
int main()
{
vector<int> arr={1,4,2,3,3,5};
int num=count_if(arr.begin(),arr.end(),pre1);
cout<<"大于3的个数为"<<num<<endl; //2
num=count_if(arr.begin(),arr.end(),pre2());
cout<<"大于4的个数为"<<num<<endl; //1
return 0;
}
四、排序算法
4.1sort
对容器内元素进行排序,函数原型为:
sort(iterator beg, iterator end, _Pred);
其中beg是开始迭代器,end是结束迭代器,_pred是谓词
示例如下:
void print1(int m)
{
cout<<m<<" ";
}
int main()
{
vector<int> arr={1,4,2,3,3,5};
sort(arr.begin(),arr.end());
for_each(arr.begin(),arr.end(),print1);//1,2,3,3,4,5
sort(arr.begin(),arr.end(),greater<int>());//降序
for_each(arr.begin(),arr.end(),print1);//5,4,3,3,2,1
return 0;
}
示例2:使用自定义排序规则
int pre1(int m,int n)
{
return m>n;
}
class pre2{
public:
bool operator()(int m,int n)
{
return m>n;
}
};
int main()
{
vector<int> arr={1,4,2,3,3,5};
sort(arr.begin(),arr.end(),pre1);//降序
for_each(arr.begin(),arr.end(),print1);//5,4,3,3,2,1
sort(arr.begin(),arr.end(),pre2());//降序
for_each(arr.begin(),arr.end(),print1);//5,4,3,3,2,1
return 0;
}
4.2 random_shuffle
洗牌算法,指定范围内的元素随机调整次序,函数原型为:
random_shuffle(iterator beg, iterator end);
其中beg是开始迭代器,end是结束迭代器
示例如下:
void print1(int m)
{
cout<<m<<" ";
}
int main()
{
vector<int> arr={1,4,2,3,3,5};
random_shuffle(arr.begin(),arr.end());
for_each(arr.begin(),arr.end(),print1);
return 0;
}
4.3merge
两个容器合并,存储到另一个容器中,函数原型为:
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
dest是目标容器迭代器,要是容器1、容器2有序
示例如下:
void print1(int m)
{
cout<<m<<" ";
}
int main()
{
vector<int> arr={1,3,5,7,9},arr2={2,4,6,8,10};
vector<int> target;
target.resize(arr.size()+arr2.size());
merge(arr.begin(),arr.end(),arr2.begin(),arr2.end(),target.begin());
for_each(target.begin(),target.end(),print1);
return 0;
}
目标容器需要提前开辟内存空间
4.4reverse
将容器内元素进行反转,函数原型为:
reverse(iterator beg, iterator end);
示例如下:
void print1(int m)
{
cout<<m<<" ";
}
int main()
{
vector<int> arr={1,3,5,7,9};
for_each(arr.begin(),arr.end(),print1);
reverse(arr.begin(),arr.end());
for_each(arr.begin(),arr.end(),print1);//9,7,5,3,1
return 0;
}
五、拷贝和替换算法
5.1copy
容器指定范围内的元素拷贝到另一个容器中
copy(iterator beg, iterator end, iterator dest);
示例如下:
vector<int> arr={1,3,5,7,9};
vector<int> target;
target.resize(arr.size());
copy(arr.begin(),arr.end(),target.begin());
5.2replace
容器指定范围内的元素替换为新元素
replace(iterator beg, iterator end, oldvalue, newvalue);
示例如下:
void print1(int m)
{
cout<<m<<" ";
}
int main()
{
vector<int> arr={1,3,3,5,7,9};
replace(arr.begin(),arr.end(),3,4);
for_each(arr.begin(),arr.end(),print1);
return 0;
}
5.3replace_if
按条件替换区间内的元素,函数原型为:
replace_if(iterator beg, iterator end, _pred, newvalue);
其中_pred为函数或函数对象,newvalue为新元素
示例如下:
int pre1(int m)
{
return m>3;
}
class pre2{
public:
bool operator()(int m)
{
return m>4;
}
};
int main()
{
vector<int> arr={1,3,3,5,7,9};
replace_if(arr.begin(),arr.end(),pre1,3);//函数
for_each(arr.begin(),arr.end(),print1);//1,3,3,3,3,3
arr={1,3,3,5,7,9};
replace_if(arr.begin(),arr.end(),pre2(),4);//函数对象
for_each(arr.begin(),arr.end(),print1);///1,3,3,4,4,4
return 0;
}
5.4 swap
互换2个容器的元素
swap(container c1, container c2);
示例如下:
vector<int> arr={1,3,3,5,7,9};
vector<int> arr2={2,4,6,8,10};
swap(arr,arr2);
for_each(arr.begin(),arr.end(),print1);
cout<<endl;
for_each(arr2.begin(),arr2.end(),print1);
六、算术生成算法
使用时需要包含头文件#include<numeric>
6.1accumulate
计算容器内元素总和
accumulate(iterator beg, iterator end, value);
返回元素内总和的值,其中val表示起始值
示例如下:
vector<int> arr={1,3,3,5,7,9};
int sum=accumulate(arr.begin(),arr.end(),0);
cout<<sum<<endl;
6.2fill
向容器中填充指定的元素
fill(iterator beg, iterator end, value);
其中val表示要填充的值
示例如下:
void print1(int m)
{
cout<<m<<" ";
}
int main()
{
vector<int> arr={1,3,3,5,7,9};
fill(arr.begin(),arr.end(),0);
for_each(arr.begin(),arr.end(),print1);
return 0;
}
七、常用集合算法
7.1set_intersection
求2个集合的交集
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
返回目标容器最后一个迭代器的地址
注意:两个集合必须是有序序列。
示例如下:
void print1(int m)
{
cout<<m<<" ";
}
int main()
{
vector<int> arr={1,3,3,5,7,9};
vector<int> arr2={1,3,5,7,9};
vector<int> target;
target.resize(min(arr.size(),arr2.size()));
//返回的是目标容器最后一个元素的地址,不接受该地址也可以
//auto it=set_intersection(arr.begin(),arr.end(),arr2.begin(),arr2.end(),target.begin());
set_intersection(arr.begin(),arr.end(),arr2.begin(),arr2.end(),target.begin());
for_each(target.begin(),target.end(),print1);
return 0;
}
7.2set_union
求集合的并集
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
返回目标容器的最后一个元素的地址。
注意:两个集合必须是有序序列
示例如下:
void print1(int m)
{
cout<<m<<" ";
}
int main()
{
vector<int> arr={1,3,3,5,7,9};
vector<int> arr2={1,3,5,7,9};
vector<int> target;
//target.resize(max(arr.size(),arr2.size()));
target.resize(arr.size()+arr2.size());
auto it=set_union(arr.begin(),arr.end(),arr2.begin(),arr2.end(),target.begin());
//set_union(arr.begin(),arr.end(),arr2.begin(),arr2.end(),target.begin());
for_each(target.begin(),it,print1);
return 0;
}
注意:并集目标容器的大小取2个容器大小相加的值
7.3set_difference
求两个集合的差集
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
注意:两个集合必须是有序序列
示例如下:
void print1(int m)
{
cout<<m<<" ";
}
int main()
{
vector<int> arr={1,3,3,5,7,9};
vector<int> arr2={1,3,5,7,9};
vector<int> target;
target.resize(max(arr.size(),arr2.size()));
auto it=set_difference(arr.begin(),arr.end(),arr2.begin(),arr2.end(),target.begin());
for_each(target.begin(),it,print1);
return 0;
}