C++ STL学习笔记--------算法 <algorithm>中各种算法解析
一、巡防算法
for_each(容器的起始地址,容器的结束地址,要执行的方法)
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
template<class T>
struct plus2
{
void operator()(T &x)const{
x+=2;
}
};
void printElem(int & elem)
{
cout<<elem<<endl;
}
int main()
{
int ia[]= {0,1,2,3,4,5,6};
for_each(ia,ia+7,printElem); //输出
int ib[] = {7,8,9,10,11,12,13};
vector<int> iv(ib,ib+7);
for_each(iv.begin(),iv.end(),plus2<int>()); //更改数据
for_each(iv.begin(),iv.end(),printElem);
return 0;
}
二、find算法
int *find(int *begin,int *end,int value);
前闭后合的区间begin,end中,查找value如果查找到了就返回第一个符合条件的元素,否则返回end指针
#include <iostream>
#include<algorithm>
using namespace std;
void printElen(int & elem)
{
cout<<elem<<endl;
}
int main()
{
int ia[] = {0,1,2,3,4,5,6};
int *i = find (ia,ia+7,9);//在整个数组中查找元素 9
int *j = find(ia,ia+7,3);//在整个数组中查找元素 3
int *end = ia+7;//数组最后位置
if(i==end)
cout<<"没有找到元素9"<<endl;
else
cout<<"找到元素9"<<endl;
if(j==end)
cout<<"没有找到元素3"<<endl;
else
cout<<"找到元素3"<<endl;
return 0;
}
三、数值算法
包含在<numeric>头文件中
accumlate(容器起始位置begin,容器结束位置end,初值0) 累加
accumlate(容器起始位置begin,容器结束位置end,初值0,minus<int>()) 累加 符号位负
inner_produxr(容器起始位置begin,容器结束位置end,容器起始位置begin,初值) 两个数组内积 初值+每个元素自己乘积
inner_produxr(容器起始位置begin,容器结束位置end,容器起始位置begin,初值,minus<int>(),plus<int>()) 初值-(每个元素的和)
partial_sum(容器起始位置begin,容器结束位置end,另一个容器起始位置begin); 在每一位时计算包括该位和前面的累加和 结果放在另一个数组中
返回一个迭代器,作为新的数组的结束end
partial_sum(容器起始位置begin,容器结束位置end,另一个容器起始位置begin,minus<int>()); 累计减法 依次输出第一个数减去(除第一个数外到当前数的和)
adjacent_difference(容器起始位置begin,容器结束位置end,另一个容器起始位置begin); 输出相邻元素差值 前面-后面
pow(a,b); a的b次方
#include <iostream>
#include<numeric>
#include<vector>
#include<iterator>
#include <algorithm>
#include<math.h>
#include<functional>
using namespace std;
void printElem(int & elem)
{
cout<<elem<<" ";
}
int main()
{
int ia[] = {1,2,3,4,5};
vector<int> iv(ia,ia+5);
cout<<accumulate(iv.begin(),iv.end(),0)<<endl; //累加,初值为0
cout<<accumulate(iv.begin(),iv.end(),0,minus<int>())<<endl; //累加,符号位负
cout<<inner_product(iv.begin(),iv.end(),iv.begin(),10)<<endl;//两个数组内积 初值为10
//10+1*1+2*2+3*3+4*4+5*5=65
cout<<inner_product(iv.begin(),iv.end(),iv.begin(),10,minus<int>(),plus<int>())<<endl;
//10-(1+1)-(2+2)-(3+3)-(4+4)-(5+5)=-20
ostream_iterator<int> oite(cout," ");//迭代器绑定到cout上作为输出使用
partial_sum(iv.begin(),iv.end(),oite); //依次输出前n个数的和
cout<<endl;
vector<int> iv2(ia,ia+5);
vector<int> ::iterator destEnd = partial_sum(iv.begin(),iv.end(),iv2.begin());//在每一位时计算包括该位和前面的累加和 结果放在另一个数组中
for_each(iv2.begin(),destEnd,printElem); //输出
cout<<endl;
partial_sum(iv.begin(),iv.end(),oite,minus<int>());//累计减法 依次输出第一个数减去(除第一个数外到当前数的和)
//1 1-2 1-2-3 1-2-3-4 1-2-3-4-5
cout<<endl;
adjacent_difference(iv.begin(),iv.end(),oite); //输出相邻元素差值 前面-后面
cout<<endl;
cout<<pow(10,3)<<endl; // 平方
return 0;
}
四,基本算法
#include <iostream>
#include <set>
#include <algorithm>
#include <iterator>
#include<vector>
using namespace std;
template <class T>
struct display
{
void operator()(const T &x)
{
cout<<x<<" ";
}
};
int main()
{
int ia1[]={1,3,5,7,9,11};
int ia2[]={1,2,3,5,8,13};
multiset<int> s1(ia1,ia1+6);
multiset<int> s2(ia2,ia2+6);
for_each(s1.begin(),s1.end(),display<int>());
cout<<endl;
for_each(s2.begin(),s2.end(),display<int>());
cout<<endl;
multiset<int>::iterator first1 = s1.begin();
multiset<int>::iterator last1 = s1.end();
multiset<int>::iterator first2 = s2.begin();
multiset<int>::iterator last2 = s2.end();
cout<<"union of s1 and s2: ";
//两个集合合并,相同元素个数取 max(m,n)。
set_union(first1,last1,first2,last2,ostream_iterator<int>(cout," "));
cout<<endl;
first1=s1.begin();
first2=s2.begin();
cout<<"Intersection of s1 and s2: ";
//两个集合交集,相同元素个数取 min(m,n).
set_intersection(first1,last1,first2,last2,ostream_iterator<int>(cout," "));
cout<<endl;
first1=s1.begin();
first2=s2.begin();
cout<<"Intersection of s1 and s2: ";
//两个集合差集 就是去掉S1中 的s2
set_difference(first1,last1,first2,last2,ostream_iterator<int>(cout," "));
cout<<endl;
first1=s1.begin();
first2=s2.begin();
cout<<"Intersection of s1 and s2: ";
//两个集合对称差集:就是取两个集合互相没有的元素 。两个排序区间,元素相等指针后移,不等输出小的并前进
//相同元素的个数 abs(m-n)
set_symmetric_difference(first1,last1,first2,last2,ostream_iterator<int>(cout," "));
cout<<endl;
iv.push_back(2);//在最后插入元素 1
return 0;
}
mismatch(容器起始位置begin,容器结束位置end,另一个容器起始位置begin); 判断两个的数组不匹配的第一个元素
返回一个迭代器,first指向第一个数组的元素,second指向第二个数组的元素(不同的)
equal算法也是逐一比较两个序列的元素是否相等,只是equal函数的返回值为bool值true/false,不是返回迭代器值。
迭代器区间[first1,last1)和迭代器区间[first2, first2+(last1 - first1))上的元素相等(或者满足二元谓词判断条件binary_pred) ,返回true,否则返回false。
equal((容器起始位置begin,容器结束位置end,另一个容器起始位置begin)<<endl; 1 表示 相等, 0不相等 并且只比较跟 iv1长度大小的数组
equal和mismatch算法的功能是比较容器中的两个区间内的元素。这两个算法各有3个参数first1,last1和first2.如果对于区间[first1,last1)内所有的first1+i,first1+i和first2所在位置处的元素都相等,则equal算法返回真,否则返回假。mismatch算法的返回值是由两个迭代器first1+i和first2+i组成的一个pair,表示第1对不相等的元素的位置。如果没有找到不相等的元素,则返回last1和first2+(last1-first1)。因此,语句
equal(first1,last1,first2)和mismatch(first1,last1,first2).first==last1是等价的
fill(容器起始位置begin,容器结束位置end,值); 将容器区间内填满 指定值
fill_n(容器起始begin,n,数值); 从容器开始填 n个指定值 其余不变
iter_swap(*迭代器1,*迭代器2);
swap(*迭代器1,*迭代器2); 交换迭代器指向的元素
max(*迭代器1,*迭代器2); 两个迭代器当前指向位置的最大值
min(*迭代器1,*迭代器2); 两个迭代器当前指向位置的最小值
lexicographical_compare(容器1起始位置begin,容器1结束位置end,容器2起始位置begin,容器2结束位置end) 按照字典序 前者小于后者
lexicographical_compare(容器1起始位置begin,容器1结束位置end,容器2起始位置begin,容器2结束位置end,greater<string>()) 按照字典序 前者不大于后者
如果[first1, last1)按字典序列小于[first2, last2),返回true,否则返回false。 所谓字典序比较,指的是两个序列分别从第一个开始一一按照字典序进行比较,如果相同位置的元素相同,则继续向后比较,直到相同位置出现不同的元素为止。没有相同的返回0
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
template<typename T>
struct display
{
void operator()(const T &x)const
{
cout<<x<<" ";
}
};
int main()
{
int ia[]={0,1,2,3,4};
int ib[] = {1,1,2,3,4};
vector<int> iv1(ia,ia+5);
vector<int> iv2(ib,ib+5);
cout<<endl;
pair<vector<int>::iterator,vector<int>::iterator> pa;
pa=mismatch(iv1.begin(),iv1.end(),iv2.begin()); //判断两个的数组不匹配的第一个元素
cout<<"两个数组不同点--第一个数组点:"<<*(pa.first)<<endl; //这样写很危险,应该判断是否到达end
cout<<"两个数组不同点--第二个数组点:"<<*(pa.second)<<endl;
if(pa.first == iv1.end())
cout<<"第一个数组与第二个数组匹配"<<endl;
//equal算法也是逐一比较两个序列的元素是否相等,只是equal函数的返回值为bool值true/false,不是返回迭代器值。
//迭代器区间[first1,last1)和迭代器区间[first2, first2+(last1 - first1))上的元素相等(或者满足二元谓词判断条件binary_pred) ,返回true,否则返回false。
cout<<equal(iv1.begin(),iv1.end(),iv2.begin())<<endl; // 1 表示 相等, 0不相等 并且只比较跟 iv1长度大小的数组
cout<<equal(iv1.begin(),iv1.end(),&ia[3])<<endl;// 0 表示 不相等
cout<<equal(iv1.begin(),iv1.end(),&ia[3],less<int>())<<endl;// 1 表示 前者小于后者
fill(iv1.begin(),iv1.end(),9); //将iv1区间内填满 9
for_each(iv1.begin(),iv1.end(),display<int>());
cout<<endl;
fill_n(iv1.begin(),3,6);//从iv1区间开始填 3个6 其余不变
for_each(iv1.begin(),iv1.end(),display<int>());
cout<<endl;
vector<int>::iterator ite1=iv1.begin();
vector<int>::iterator ite2=ite1;
advance(ite2,3);//向前跳3个
iter_swap(ite1,ite2);//交换迭代器指向的元素
for_each(iv1.begin(),iv1.end(),display<int>());
cout<<endl;
cout<<"\nmax:"<<max(*ite1,*ite2)<<endl; //两个迭代器当前指向位置的最大值
cout<<"min:"<<min(*ite1,*ite2)<<endl;//最小值
swap(*ite1,*ite2);
for_each(iv1.begin(),iv1.end(),display<int>());
cout<<endl;
string stra1[]={"a","g","c"};
string stra2[]={"d","e","f"};
cout<<endl;
//如果[first1, last1)按字典序列小于[first2, last2),返回true,否则返回false。
//所谓字典序比较,指的是两个序列分别从第一个开始一一按照字典序进行比较,如果相同位置的元素相同,则继续向后比较,直到相同位置出现不同的元素为止。
//没有相同的返回0
cout<<lexicographical_compare(stra1,stra1+2,stra2,stra2+2)<<endl;//按照字典序 前者小于后者
cout<<lexicographical_compare(stra1,stra1+2,stra2,stra2+2,greater<string>())<<endl;//按照字典序 前者不大于后者
return 0;
}
五,copy()对不同容器复制;关于输出区间与输入区间重叠的讨论