算法概述
算法主要是由头文件algorithm、 functional、numeric组成。
algorithm :是所有STL头文件中最大的一个,其中常用的功能涉及到比较,交换,查找,遍历,复制,修改,反转,排序,合并等…
numeric :体积很小,只包括在几个序列容器上进行的简单运算的模板函数.
functional :定义了一些模板类,用以声明函数对象。
常用遍历算法
遍历算法 遍历容器元素
@param beg 开始迭代器
@param end 结束迭代器
@param _callback 函数回调或者函数对象
@return 函数对象
for_each(iterator beg, iterator end, _callback);
#include<iostream>
#include<string>
#include<vector>
#include<functional>
#include<numeric>
#include<algorithm>
using namespace std;
//for_each(iterator beg, iterator end, _callback);
//transform(iterator beg1, iterator end1, iterator beg2, _callbakc)
class myprint01
{
public:
void operator()(int val)
{
cout<<val<<" ";
count++;
}
int count;
};
class myprint:public binary_function<int,int,void>
{
public:
void operator()(int val,int num) const
{
cout<<val+num<<" ";
}
int count;
};
void test01()
{
vector<int> p;
for(int i =0;i<5;i++)
p.push_back(i);
//for_each基本用法
for_each(p.begin(),p.end(),[](int val){cout<<val<<" ";});
cout<<endl;
//for_each 可以保存内部记录
myprint01 p1 = for_each(p.begin(),p.end(),myprint01());
cout<<endl;
cout<<p1.count<<endl;
// 绑定参数
for_each(p.begin(),p.end(),bind2nd(myprint(),100));
cout<<endl;
}
//transform 将一个容器中的值搬运到另一个容器中
class mytransform
{
public:
int operator()(int val)
{
return val;
}
};
class mytransform02
{
public:
int operator()(int val1,int val2)
{
return val1+val2;
}
};
transform算法 将指定容器区间元素搬运到另一容器中
注意 : transform 不会给目标容器分配内存,所以需要我们提前分配好内存
@param beg1 源容器开始迭代器
@param end1 源容器结束迭代器
@param beg2 目标容器开始迭代器
@param _cakkback 回调函数或者函数对象
@return 返回目标容器迭代器
transform(iterator beg1, iterator end1, iterator beg2, _callbakc)
void test02()
{
//容器1转到容器2
vector<int> p;
for(int i =5;i>0;i--)
p.push_back(i);
vector<int> p1;
p1.resize(p.size());
vector<int>::iterator pos = transform(p.begin(),p.end(),p1.begin(),mytransform());
for_each(p1.begin(),p1.end(),myprint01());
cout<<endl;
for_each(p.begin(),p.end(),myprint01());
cout<<endl;
//容器12的和转到容器3
vector<int>p3;
p3.resize(p.size());
vector<int>::iterator it = transform(p.begin(),p.end(),p1.begin(),p3.begin(),mytransform02());
for_each(p3.begin(),p3.end(),myprint01());
cout<<endl;
}
常用查找算法
/*
find算法 查找元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return 返回查找元素的位置
*/
find(iterator beg, iterator end, value)
/*
find_if算法 条件查找
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 回调函数或者谓词(返回bool类型的函数对象)
@return bool 查找返回true 否则false
*/
find_if(iterator beg, iterator end, _callback);
/*
adjacent_find算法 查找相邻重复元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param _callback 回调函数或者谓词(返回bool类型的函数对象)
@return 返回相邻元素的第一个位置的迭代器
*/
adjacent_find(iterator beg, iterator end, _callback);
/*
binary_search算法 二分查找法
注意: 在无序序列中不可用
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return bool 查找返回true 否则false
*/
// 必须是有序非递减序列
bool binary_search(iterator beg, iterator end, value);
/*
count算法 统计元素出现次数
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value回调函数或者谓词(返回bool类型的函数对象)
@return int返回元素个数
*/
count(iterator beg, iterator end, value);
/*
count算法 统计元素出现次数
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 回调函数或者谓词(返回bool类型的函数对象)
@return int返回元素个数
*/
count_if(iterator beg, iterator end, _callback);
示例:
class greater01
{
public:
bool operator()(int val)
{
if(val < 5)
return true;
return false;
}
};
void test03()
{
vector<int> p;
for(int i =5;i>0;i--)
p.push_back(i);
for_each(p.begin(),p.end(),[](int val){cout<<val<<" ";});
cout<<endl;
//find 返回迭代器 未找到返回p.end()
vector<int>::iterator pos = find(p.begin(),p.end(),5);
if(pos != p.end())
cout<<*pos<<endl;
else
{
cout<<"未找到"<<endl;
}
// 返回迭代器 未找到返回p.end()
vector<int>::iterator pos1 = find_if(p.begin(),p.end(),greater01());
cout<<*pos1<<endl;
// 返回迭代器 查找相邻元素是否相等
vector<int>::iterator it = adjacent_find(p.begin(),p.end());
if(it != p.end())
cout<<*it<<endl;
else
{
cout<<"未找到"<<endl;
}
vector<int> p1;
for(int i =0;i<5;i++)
p1.push_back(3);
//若在有序数组(要求数组元素非递减)中查找到indx元素则真
bool ret = binary_search(p1.begin(),p1.end(),3);
cout<<ret<<endl; // 1 找到了
//count count_if 都返回int if可以查找条件
int num = count(p1.begin(),p1.end(),3); // 3的个数5个
cout<<num<<endl;
int num1 = count_if(p.begin(),p.end(),greater01()); // 小于5 的个数为4
cout<<num1<<endl;
}
排序算法
merge算法 容器元素合并,并存储到另一容器中
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
//merge 容器元素合并,并存储到另一容器中
//俩个容器必须有序,同时升序降序要相同
vector<int> p1,p2;
for(int i =0;i<5;i++)
{
p1.push_back(i+5);
p2.push_back(i*2);
}
vector<int> p3;
p3.resize(p1.size()+p2.size());
merge(p1.begin(),p1.end(),p2.begin(),p2.end(),p3.begin());
for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
cout<<endl;
sort算法 容器元素排序
@param beg 容器1开始迭代器
@param end 容器1结束迭代器
@param _callback 回调函数或者谓词(返回bool类型的函数对象)
sort(iterator beg, iterator end, _callback)
//sort排序算法 默认升序
sort(p3.begin(),p3.end());
for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
cout<<endl;
sort(p3.begin(),p3.end(),greater<int>());
for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
cout<<endl;
random_shuffle算法 对指定范围内的元素随机调整次序
@param beg 容器开始迭代器
@param end 容器结束迭代器
random_shuffle(iterator beg, iterator end)
//random_shuffle(iterator beg, iterator end) 随机排序
//为了随机需要在主函数添加srand((unsigned int)time(NULL));
random_shuffle(p3.begin(),p3.end());
for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
cout<<endl;
reverse算法 反转指定范围的元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
reverse(iterator beg, iterator end)
//reverse(iterator beg, iterator end) 反转算法
sort(p3.begin(),p3.end()); // 排序后升序
reverse(p3.begin(),p3.end()); // 变为降序
for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
cout<<endl;
全部的排序算法代码:
// 常用排序算法
void test04()
{
//merge 容器元素合并,并存储到另一容器中
//俩个容器必须有序,同时升序降序要相同
vector<int> p1,p2;
for(int i =0;i<5;i++)
{
p1.push_back(i+5);
p2.push_back(i*2);
}
vector<int> p3;
p3.resize(p1.size()+p2.size());
merge(p1.begin(),p1.end(),p2.begin(),p2.end(),p3.begin());
for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
cout<<endl;
//sort排序算法 默认升序
sort(p3.begin(),p3.end());
for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
cout<<endl;
sort(p3.begin(),p3.end(),greater<int>());
for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
cout<<endl;
//random_shuffle(iterator beg, iterator end) 随机排序
//为了随机需要在主函数添加srand((unsigned int)time(NULL));
random_shuffle(p3.begin(),p3.end());
for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
cout<<endl;
//reverse(iterator beg, iterator end) 反转算法
sort(p3.begin(),p3.end()); // 排序后升序
reverse(p3.begin(),p3.end()); // 变为降序
for_each(p3.begin(),p3.end(),[](int val){cout<<val<<" ";});
cout<<endl;
}
常见拷贝和替换算法
/*
copy算法 将容器内指定范围的元素拷贝到另一容器中
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param dest 目标起始迭代器
*/
copy(iterator beg, iterator end, iterator dest)
/*
replace算法 将容器内指定范围的旧元素修改为新元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param oldvalue 旧元素
@param oldvalue 新元素
*/
replace(iterator beg, iterator end, oldvalue, newvalue)
/*
replace_if算法 将容器内指定范围满足条件的元素替换为新元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback函数回调或者谓词(返回Bool类型的函数对象)
@param oldvalue 新元素
*/
replace_if(iterator beg, iterator end, _callback, newvalue)
/*
swap算法 互换两个容器的元素
@param c1容器1
@param c2容器2
*/
swap(container c1, container c2)
代码示例:
// 常用拷贝和替换算法
class compare
{
public:
bool operator()(int val)
{ if(val < 5)
return true;
return false;
}
};
void test05()
{
vector<int>p;
for (int i = 0; i < 5; i++)
{
p.push_back(i);
}
vector<int>p1;
p1.resize(p.size());
//copy
copy(p.begin(),p.end(),p1.begin());
//for_each(p1.begin(),p1.end(),[](int val){cout<<val<<" ";});
//直接输出 添加头文件iterator
copy(p1.begin(),p1.end(),ostream_iterator<int>(cout," "));
cout<<endl;
vector<int>p2;
for (int i = 0; i < 10; i++)
{
p2.push_back(i+1);
}
// 需求 把容器中的 3替换为300
replace(p2.begin(),p2.end(),3,300);
copy(p2.begin(),p2.end(),ostream_iterator<int>(cout," "));
cout<<endl;
// 小于5 的数替换为100
replace_if(p2.begin(),p2.end(),compare(),100);
copy(p2.begin(),p2.end(),ostream_iterator<int>(cout," "));
cout<<endl;
// swap算法 互换两个容器的元素
swap(p1,p2);
copy(p1.begin(),p1.end(),ostream_iterator<int>(cout," "));
cout<<endl;
copy(p2.begin(),p2.end(),ostream_iterator<int>(cout," "));
cout<<endl;
}
常用常数生成算法
使用前需要添加头文件***numeric***
很简单的使用方式需要熟练使用
/*
accumulate算法 计算容器元素累计总和
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value累加值
*/
accumulate(iterator beg, iterator end, value)
/*
fill算法 向容器中添加元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value t填充元素
*/
fill(iterator beg, iterator end, value)
代码示例:
// 常用算术生成
void test06()
{
//accumulate算法 计算容器元素累计总和
vector<int>p;
for (int i = 0; i < 10; i++)
{
p.push_back(i+1);
}
copy(p.begin(),p.end(),ostream_iterator<int>(cout," "));
int num = accumulate(p.begin(),p.end(),0);
cout<<num<<endl;
//计算出的总和再加上累加值 10 55+10 = 65
num = accumulate(p.begin(),p.end(),10);
cout<<num<<endl;
// fill算法 向容器中添加元素
cout<<"fill填充:"<<endl;
fill(p.begin(),p.end(),10);
copy(p.begin(),p.end(),ostream_iterator<int>(cout," "));
cout<<endl;
}
常用集合算法
基本不怎么会用到,了解即可。
/*
set_intersection算法 求两个set集合的交集
注意:两个集合必须是有序序列
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
*/
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
/*
set_union算法 求两个set集合的并集
注意:两个集合必须是有序序列
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
*/
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
/*
set_difference算法 求两个set集合的差集
注意:两个集合必须是有序序列
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
*/
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
代码示例:
// 常用集合算法
void test07()
{
//set_intersection算法 求两个set集合的交集
vector<int>p,p1;
for(int i =0;i<5;i++)
{
p.push_back(i+1); // 12345
p1.push_back(i+2); // 23456
}
vector<int>p2;
//容器体积按照最坏情况即p p1 交集是其中一个集合,即p p1有可能是包容和被包容的关系
//俩个集合中小的那个即可
p2.resize(min(p.size(),p1.size()));
vector<int>::iterator pos = set_intersection(p1.begin(),p1.end(),p.begin(),p.end(),p2.begin()); // 23450
//返回当前目标容器的最后一个元素的迭代器地址,因为容器的容量可能会大于他的元素个
copy(p2.begin(),p2.end(),ostream_iterator<int>(cout," ")); // 23450
cout<<endl;
//使用迭代器POS后完美显示出元素
copy(p2.begin(),pos,ostream_iterator<int>(cout," "));
cout<<endl;
// set_union算法 求两个set集合的并集 注意:两个集合必须是有序序列
//容器应该按照最坏情况即p1 p 没有交集,并集是俩个集合的总和
p2.resize(p.size()+p1.size());
vector<int>::iterator pos1 = set_union(p.begin(),p.end(),p1.begin(),p1.end(),p2.begin()); // 123456
copy(p2.begin(),pos1,ostream_iterator<int>(cout," "));
cout<<endl;
// set_difference算法 求两个set集合的差集 p-p1 = 1 p1- p = 6
//差集 即俩个集合的不同元素,最坏没有交集,即容器要包括最大的一个集合所有元素
p2.resize(max(p1.size(),p.size()));
// p 差 p1 1
vector<int>::iterator pos2 = set_difference(p.begin(),p.end(),p1.begin(),p1.end(),p2.begin());
copy(p2.begin(),pos2,ostream_iterator<int>(cout," "));
cout<<endl;
// p1 差 p 6
vector<int>::iterator pos3 = set_difference(p1.begin(),p1.end(),p.begin(),p.end(),p2.begin());
copy(p2.begin(),pos3,ostream_iterator<int>(cout," "));
cout<<endl;
}