c++ STL-适配器、算法
1. 函数对象
1.1 概念
重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象,也叫仿函数(functor), 其实就是 重载“()”操作符
,使得 类对象 可以 像函数 那样调用。
作用:为算法提供策略。
注意:
- 函数对象(仿函数)是一个类,不是一个函数。
- 函数对象(仿函数)重载了”() ”操作符使得它可以像函数一样调用。
1.2 函数对象的分类
一元仿函数(unary_functor): 重载的 operator()要求获取一个参数
二元仿函数(binary_functor): 重载的operator()要求获取两个参数
1.3 示例
#include <iostream>using namespace std;
class Add{
public:void operator ()(int a, int b){cout << a + b << endl;}
};int main(int argc, char *argv[])
{Add add01;add01(1,3); //4add01(4,5); //9//匿名对象Add()(5,6); //11return 0;
}
【小结】:
1、函数对象通常不定义构造函数和析构函数,所以在构造和析构时不会发生任何问题,避免了函数调用的运行时问题。
2、函数对象超出普通函数的概念,函数对象可以有自己的状态
3、函数对象可内联编译、性能好,用函数指针几乎不可能
4、模版函数对象使函数对象具有通用性,这也是它的优势之一
2. 谓词
谓词是 指 普通函数
或 重载的 operator()
返回值是 bool 类型的函数对象(即仿函数),依据函数接收的参数又分为 一元谓词
和 二元谓词
等,谓词可作为一个判断式。
- 有一个参数 叫 一元谓词。
- 有二个参数 叫 二元谓词。
如:
gt 大于, ge 大于等于, lt小于, le小于等于, eq 等于, ne 不等于
示例:
#include <iostream>using namespace std;
//这种函数被称为一元谓词
bool isCN(int age)
{if(age >= 18){return true;}return false;
}
//这种函数被称为二元谓词
bool test(int a,int b){return false;
}class A{
public:bool operator()(int a){}
};class B{
public:bool operator()(int a,int b){}
};
int main(int argc, char *argv[])
{A()(1);B()(1,3);return 0;
}
3. 内建函数
引入头文件
#include <algorithm>
STL 内建了一些函数对象, 分为 算数类函数对象
、关系运算类函数对象
、逻辑运算类仿函数
等。这些仿函数所产生的对象,用法和一般函数完全相同,当然我们还可以产生无名的临时对象来履行函数功能。
3.1 算数类函数对象
template<class T> T plus<T>//加法仿函数
template<class T> T minus<T>//减法仿函数
template<class T> T multiplies<T>//乘法仿函数
template<class T> T divides<T>//除法仿函数
template<class T> T modulus<T>//取模仿函数
template<class T> T negate<T>//取反仿函数
6 个算数类函数对象,除了 negate 是一元运算,其他都是二元运算。
示例1:
#include <iostream>
using namespace std;
void fun01()
{/*
template<class T> T plus<T>//加法仿函数
template<class T> T minus<T>//减法仿函数
template<class T> T multiplies<T>//乘法仿函数
template<class T> T divides<T>//除法仿函数
template<class T> T modulus<T>//取模(取余)仿函数
template<class T> T negate<T>//取反仿函数*/int num01 = plus<int>()(1,5);cout << num01 << endl; //6plus<int> pl;int num02 = pl(2,6);cout << num02 << endl; //8cout << minus<double>()(5,1) << endl; //4cout << multiplies<double>()(5,2) << endl; //10cout << divides<int>()(5,2) << endl; //2cout << modulus<int>()(5,2) << endl; //1cout << negate<int>()(5) << endl; //-5cout << negate<int>()(-5) << endl; //5
}
示例2:自定义
template<class X>
class Add{
public:X operator()(X x1,X x2){return x1+x2;}
};
void fun04()
{cout << Add<int>()(1,4) << endl;
}
3.2 关系运算类函数对象
template<class T> bool equal_to<T>//等于
template<class T> bool not_equal_to<T>//不等于
template<class T> bool greater<T>//大于
template<class T> bool greater_equal<T>//大于等于
template<class T> bool less<T>//小于
template<class T> bool less_equal<T>//小于等于
6 个关系运算类函数对象,每一种都是二元谓词
示例1:普通比较
void fun02()
{/*
template<class T> bool equal_to<T>//等于
template<class T> bool not_equal_to<T>//不等于
template<class T> bool greater<T>//大于
template<class T> bool greater_equal<T>//大于等于
template<class T> bool less<T>//小于
template<class T> bool less_equal<T>//小于等于*/cout << equal_to<int>()(10,10) << endl; //1cout << equal_to<int>()(10,1) << endl; //0 cout << not_equal_to<int>()(10,1) << endl; //1cout << greater<int>()(10,1) << endl; //1cout << greater_equal<int>()(10,1) << endl; //1cout << greater_equal<int>()(10,10) << endl; //1cout << greater_equal<int>()(10,11) << endl; //0cout << less<int>()(10,1) << endl; //0cout << less_equal<int>()(10,11) << endl; //1
}
示例2:应用于比较
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
void fun03()
{int nums[] = {99,24,54,12,5,7,89,66};vector<int> vs;vs.assign(nums,nums+8);//两参//sort(vs.begin(),vs.end());//三参,有比较sort(vs.begin(),vs.end(),greater<int>());//遍历输出,lambad表达式for_each(vs.begin(),vs.end(),[](int v){cout << v << " ";});cout << endl;
}
//99 89 66 54 24 12 7 5
3.3 逻辑运算类运算函数
template<class T> bool logical_and<T>//逻辑与
template<class T> bool logical_or<T>//逻辑或
template<class T> bool logical_not<T>//逻辑非
3个逻辑运算类运算函数,not 为一元谓词,其余为二元谓词。
4. 适配器
绑定:
bind2nd将绑定的数据放置第二个参数位置
bind1st将绑定的数据放置第一个参数位置bind1st和bind2nd 将二元函数对象转为一元函数对象
4.1 引入
现在我有这个需求 在遍历容器的时候,我希望将容器中的值全部加上 100 之后显示出来,怎么做?
尝试:
//1.直接在打印时+100 void fun01() {vector<int> vs;vs.push_back(10);vs.push_back(30);vs.push_back(50);//1、迭代器打印输出vector<int>::iterator it = vs.begin();for(; it != vs.end(); it++){cout << *it + 100 << " ";}cout << endl; } //110 130 150
需要我们自己的函数对象继承
binary_function
或者nary_function
4.2 函数指针适配器
4.2.1 特点
将
普通函数地址
作为适配器
- 应用 ptr_fun(函数名)
- 【注意】仿函数的参数不能使用引用
4.1.3 示例
void print01(int v)
{cout << v+100 << " ";
}
void print02(int v,int x)
{
// cout << v + x << " ";//证明绑定参数位置cout << v << " " << x << " ";
}
void fun02()
{vector<int> vs;vs.push_back(10);vs.push_back(30);vs.push_back(50);//2、STL提供的算法for_each遍历//2.1 普通函数+100 写死直接遍历for_each(vs.begin(), vs.end(), print01);cout << endl;//2.2 适配器,//print02此时为全局函数,所以此处是函数指针适配器, bind1st绑定在第一个参数上for_each(vs.begin(), vs.end(), bind1st(ptr_fun(print02), 100));cout << endl;//bind1st绑定在第二个参数上for_each(vs.begin(), vs.end(), bind2nd(ptr_fun(print02), 100));cout << endl;
}
//110 130 150
//100 10 100 30 100 50
//10 100 30 100 50 100
4.2 函数对象适配器
4.2.1 特点
将
函数对象
作为适配器。
for_each(v.begin(), v.end(), bind1st(函数对象类(), x));
for_each(v.begin(), v.end(), bind2nd(函数对象类(), x));
4.2.2 步骤
1、创建一个类,使其公共继承
binary_function<T1, T2, T3>
,并进行参数萃取
- 参数萃取:
- 模板中第一个类型
T1
为重载函数调用运算符第一个参数
的数据类型- 模板中第二个类型
T2
为重载函数调用运算符第二个参数
的数据类型- 模板中第二个类型
T3
为重载函数调用运算符返回值
的数据类型2、const修饰 重载函数调用运算符,即()
3、使用bindxxx绑定函数对象与适配器
示例:
//步骤1,定义一个类,使其公共继承与binary_function,并进行参数萃取
//参数萃取
//binary_function的三个模板类型分别为
//1,重载的函数调用运算符第一个形参的数据类型
//2,重载的函数调用运算符第二个形参的数据类型
//3,重载的函数调用运算符的返回值类型
class MyPrint01:public binary_function<int,int,void>{
public://步骤2:重载函数调用运算符并使用const修饰void operator()(int v,int x) const{cout << v + x << " ";}
};
void fun03()
{vector<int> vs;vs.push_back(10);vs.push_back(20);vs.push_back(30);vs.push_back(40);vs.push_back(50);//步骤3:使用函数对象作为适配器时,需要使用bindxxx进行绑定for_each(vs.begin(),vs.end(),bind2nd(MyPrint01(),100));cout << endl;
}
//110 120 130 140 150
示例2:本月所有员工工资加2000奖金
class Staff{string name;double money;
public:Staff(){}Staff(string name,double money){this->name = name;this->money = money;}string getName(){return name;}double getMoney(){return money;}
};
class PrintStaffInfo:public binary_function<Staff,int,void>{
public:void operator()(Staff s,int money) const{cout << s.getName() << " " << s.getMoney() + money << endl;}
};
void fun04()
{vector<Staff> stas;stas.push_back(Staff("张三",3100));stas.push_back(Staff("李四",3200));stas.push_back(Staff("王五",3000));stas.push_back(Staff("马六",10000));//将遍历出的数据作为参数传递给函数for_each(stas.begin(),stas.end(),bind2nd(PrintStaffInfo(),2000));
}
//张三 5100
//李四 5200
//王五 5000
//马六 12000
4.3 成员函数适配器
4.3.1 特点
- 将
成员函数地址
作为适配器- mem_fun_ref(&类名::函数名)
4.3.2 示例
本月所有员工工资加2000奖金
class Staff02{string name;double money;
public:Staff02(){}Staff02(string name,double money){this->name = name;this->money = money;}void print(){cout << name << " " << money << endl;}void print02(int m){cout << name << " " << money + m << endl;}
};void fun06()
{vector<Staff02> stas;stas.push_back(Staff02("张三",3100));stas.push_back(Staff02("李四",3300));stas.push_back(Staff02("王五",2100));//使用遍历出的数据调用传入的函数//for_each(stas.begin(),stas.end(),mem_fun_ref(&Staff02::print));//此时print02 只有一个形参,使用bind2nd绑定,会将实参绑定在这一个形参上,//遍历出来的数据就是第一个参数,因为是它调用函数,所以省略不写,不能使用bind1st,会报错for_each(stas.begin(),stas.end(),bind2nd(mem_fun_ref(&Staff02::print02),2000));
}//张三 5100
//李四 5300
//王五 4100
4.4 取反适配器
1)定义 unary_function<int, bool>
的函数对象类
2)应用
find_if(v.begin(), v.end(), 函数对象类());
find_if(v.begin(), v.end(), not1(函数对象类()));
// 动态给定条件
find_if(v.begin(), v.end(), not1(bind2nd(greater<int>(),5)));
sort(v.begin(), v.end(), not2(less<int>()));
// 匿名函数
for_each(v.begin(), v.end(), [](int val){cout << val << " "; });
其中的
not1
对一元函数对象取反,,not2
对二元函数对象取反。
示例:
void fun07()
{vector<int> nums;nums.push_back(10);nums.push_back(20);nums.push_back(30);nums.push_back(40);nums.push_back(50);//查找30vector<int>::iterator it = find(nums.begin(),nums.end(),30);cout << (*it) << endl;//查找大于30vector<int>::iterator it02 = find_if(nums.begin(),nums.end(),bind2nd(greater<int>(),30));cout << (*it02) << endl;//查找小于30vector<int>::iterator it03 = find_if(nums.begin(),nums.end(),bind2nd(less<int>(),30));cout << (*it03) << endl;//查找大于30,然后取反,得到小于30的vector<int>::iterator it04 = find_if(nums.begin(),nums.end(),not1(bind2nd(greater<int>(),30)));cout << (*it04) << endl;
}
//30
//40
//10
//10
示例2:自定义二元适配器仿函数,实现查找大于n的第一个容器元素, 尝试反适配
#include <iostream>
#include <vector>
#include <algorithm>
class GtN : public binary_function<int, int, bool>{
public:bool operator()(const int &n1, const int &n2) const{return n1 > n2;}
};
int main(int argc, char const *argv[])
{int m[] = {1, 2, 2, 3, 5, 10};vector<int> v(m, m + 6);// find_if(start, end, callback) 返回查找到的第一个元素的地址;vector<int>::iterator it = find_if(v.begin(), v.end(), not1(bind2nd(GtN(), 1)));cout << *it << endl;return 0;
}
//1
5. 常用算法
算法中常用的功能涉及到比较、交换、查找、遍历、复制,修改,反转,排序,合并等。
引入头文件
#include <algorithm>
5.1 遍历
5.1.2 for_caeh
语法:
/*
遍历算法 遍历容器元素
@param beg 开始迭代器
@param end 结束迭代器
@param _callback 函数回调或者函数对象
@return 函数对象
*/
for_each(iterator beg, iterator end, _callback);
示例1:遍历普通类型
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void print01(int v)
{cout << v << " " << endl;
}
void fun01()
{vector<int> nums;nums.push_back(10);nums.push_back(20);nums.push_back(30);nums.push_back(40);nums.push_back(50);//for_each(nums.begin(),nums.end(),print01);//lambad表达式for_each(nums.begin(),nums.end(),[](int v){cout << v << " ";});cout << endl;
}
//10 20 30 40 50int main(int argc, char *argv[])
{fun01();return 0;
}
示例1:遍历自定义类型
class Person{friend void printPerson(Person p);string name;int age;
public:Person(){}Person(string name,int age){this->name = name;this->age = age;}
};
void printPerson(Person p)
{cout << p.name << " " << p.age << endl;
}void fun02()
{vector<Person> ps;ps.push_back(Person("张三",18));ps.push_back(Person("李四",18));ps.push_back(Person("王五",18));ps.push_back(Person("马六",18));ps.push_back(Person("候七",18));for_each(ps.begin(),ps.end(),printPerson);
}
//张三 18
//李四 18
//王五 18
//马六 18
//候七 18
5.1.3 transform
将指定容器区间元素 搬运
到另一容器中。
【注意】不会给目标容器分配内存,所以需要我们 提前分配好内存
语法:
/*
transform 算法 将指定容器区间元素搬运到另一容器中
注意:transform 不会给目标容器分配内存,所以需要我们提前分配好内存
@param beg1 源容器开始迭代器
@param end1 源容器结束迭代器
@param beg2 目标容器开始迭代器
@param _cakkback 回调函数或者函数对象
@return 返回目标容器迭代器
*/
transform(iterator beg1, iterator end1, iterator beg2, _callbakc);/*
transform 算法 将指定容器区间元素搬运到另一容器中
注意:transform 不会给目标容器分配内存,所以需要我们提前分配好内存
@param beg1 源容器1开始迭代器
@param end1 源容器1结束迭代器
@param beg2 源容器2开始迭代器
@param result 结果
@param _cakkback 回调函数或者函数对象
@return 返回目标容器迭代器
*/
transform(iterator beg1, iterator end1, iterator beg2,iterator result,_callbakc);
示例:
void print01(int v)
{cout << v << " " << endl;
}
int setData(int v)
{return v;
}
int setData2(int v)
{return v+100;
}
void fun04()
{vector<int> nums;nums.push_back(10);nums.push_back(20);nums.push_back(30);nums.push_back(40);nums.push_back(50);vector<int> ns;//设置大小ns.resize(nums.size());//transform(nums.begin(),nums.end(),ns.begin(),setData);//中间可以加工数据transform(nums.begin(),nums.end(),ns.begin(),setData2);for_each(ns.begin(),ns.end(),print01);
}
//110
//120
//130
//140
//150
5.2 查找
5.2.1 find
作用:查找
语法:
/*
find 算法 查找元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return 返回查找到元素对应的迭代器
*/
find(iterator beg, iterator end, value)
示例:
void fun05()
{vector<int> nums;nums.push_back(10);nums.push_back(20);nums.push_back(30);nums.push_back(40);nums.push_back(50);vector<int>::iterator it = find(nums.begin(),nums.end(),30);cout << *it << endl;
}
//30
5.2.2 find_if
作用:条件查找
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 回调函数或者谓词(返回 bool 类型的函数对象)
@return 返回查找到元素对应的迭代器,找不到返回随机值
*/
find_if(iterator beg, iterator end, _callback)
示例:
void fun06()
{vector<int> nums;nums.push_back(10);nums.push_back(20);nums.push_back(30);nums.push_back(40);nums.push_back(50);vector<int>::iterator it = find_if(nums.begin(),nums.end(),bind2nd(greater<int>(),20));cout << *it << endl;
}
//30
5.2.3 adjacent_find
作用:查找相邻重复元素
/**
*adjacent_find算法 查找相邻重复元素
*@param beg容器开始迭代器
*@param end容器结束迭代器
*@param _callback回调函数或者谓词(返回bool类型的函数对象)
*@return返回相邻元素的第一个位置的迭代器
**/
adjacent_find(iterator beg, iterator end, _callback);
示例:
void fun07()
{vector<int> nums;nums.push_back(10);nums.push_back(10);nums.push_back(30);nums.push_back(30);nums.push_back(40);vector<int>::iterator it = adjacent_find(nums.begin(),nums.end());cout << *it << endl;
}
//10
5.2.4 binary_search
作用:二分查找 (必须有序)
/*
注意: 在无序序列中不可用
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return bool 查找返回 true 否则 false
*/
bool binary_search(iterator beg, iterator end, value);
示例:
void fun08()
{vector<int> nums;nums.push_back(10);nums.push_back(10);nums.push_back(30);nums.push_back(30);nums.push_back(40);bool b = binary_search(nums.begin(),nums.end(),20);cout << b << endl;bool b2 = binary_search(nums.begin(),nums.end(),30);cout << b2 << endl;
}
//0
//1
5.2.5 count
作用:统计
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 回调函数或者谓词(返回 bool 类型的函数对象)
@return int 返回元素个数
*/
count(iterator beg, iterator end, value);
示例:
void fun09()
{vector<int> nums;nums.push_back(10);nums.push_back(10);nums.push_back(30);nums.push_back(30);nums.push_back(10);int c = count(nums.begin(),nums.end(),10);cout << c << endl;
}
//3
5.2.6 count_if
作用:条件统计
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 回调函数或者谓词(返回 bool 类型的函数对象)
@return int 返回元素个数
*/
count(iterator beg, iterator end, value);
示例:
void fun10()
{vector<int> nums;nums.push_back(10);nums.push_back(10);nums.push_back(20);nums.push_back(30);nums.push_back(10);int c = count_if(nums.begin(),nums.end(),bind2nd(greater<int>(),20));cout << c << endl;
}
//1
5.3 排序
/*
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)/*
sort 算法 容器元素排序
@param beg 容器 1 开始迭代器
@param end 容器 1 结束迭代器
@param _callback 回调函数或者谓词(返回 bool 类型的函数对象)
*/
sort(iterator beg, iterator end, _callback)/*
random_shuffle 算法 对指定范围内的元素随机调整次序
@param beg 容器开始迭代器
@param end 容器结束迭代器
*/
random_shuffle(iterator beg, iterator end)/*
reverse 算法 反转指定范围的元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
*/
reverse(iterator beg, iterator end)
示例:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void fun11()
{vector<int> nums;nums.push_back(20);nums.push_back(30);nums.push_back(40);nums.push_back(10);nums.push_back(50);vector<int> nums02;nums02.push_back(70);nums02.push_back(90);nums02.push_back(60);nums02.push_back(80);nums02.push_back(100);vector<int> nums03;nums03.resize(nums.size() + nums02.size());//合并merge(nums.begin(),nums.end(),nums02.begin(),nums02.end(),nums03.begin());for_each(nums03.begin(),nums03.end(),[](int v){cout << v << " ";});cout << endl;cout << "####################" << endl;//排序sort(nums03.begin(), nums03.end());for_each(nums03.begin(),nums03.end(),[](int v){cout << v << " ";});cout << endl;cout << "####################" << endl;//打乱顺序random_shuffle(nums03.begin(),nums03.end());for_each(nums03.begin(),nums03.end(),[](int v){cout << v << " ";});cout << endl;
}void fun12()
{vector<int> vs;vs.push_back(1);vs.push_back(2);vs.push_back(3);//逆序数字reverse(vs.begin(),vs.end());for_each(vs.begin(),vs.end(),[](int v){cout << v << " ";});cout << endl;string str = "hello";//逆序字符串reverse(str.begin(),str.end());cout << str << endl;
}
int main(int argc, char *argv[])
{fun11();cout << "--------------" << endl;fun12();return 0;
}//20 30 40 10 50 70 90 60 80 100
//####################
//10 20 30 40 50 60 70 80 90 100
//####################
//90 20 100 30 10 60 80 40 50 70
//--------------
//3 2 1
//olleh
5.4 拷贝与替换
/*
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)
示例:
void fun13()
{vector<int> vs;vs.push_back(1);vs.push_back(2);vs.push_back(3);list<int> ls;//指定大小ls.resize(3);copy(vs.begin(),vs.end(),ls.begin());for_each(ls.begin(),ls.end(),[](int v){cout << v << " ";});cout << endl;
}void fun14()
{vector<int> vs;vs.push_back(1);vs.push_back(2);vs.push_back(3);vs.push_back(1);vs.push_back(2);vs.push_back(3);replace(vs.begin(),vs.end(),2,22);for_each(vs.begin(),vs.end(),[](int v){cout << v << " ";});cout << endl;
}void fun15()
{vector<int> vs;vs.push_back(1);vs.push_back(2);vs.push_back(3);vs.push_back(1);vs.push_back(2);vs.push_back(3);replace_if(vs.begin(),vs.end(),bind2nd(greater<int>(),1),100);for_each(vs.begin(),vs.end(),[](int v){cout << v << " ";});cout << endl;
}//1 2 3
//--------------
//1 22 3 1 22 3
//--------------
//1 100 100 1 100 100
5.5 算数生成
/*
accumulate 算法 计算容器元素累计总和
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 累加值, 额外加的值,可以为0
@return 累加后的数值
*/
accumulate(iterator beg, iterator end, value)
/*
fill 算法 向容器中添加元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value t 填充元素
*/
fill(iterator beg, iterator end, value)
示例:
void fun16()
{vector<int> vs;vs.push_back(1);vs.push_back(2);vs.push_back(3);vs.push_back(1);vs.push_back(2);vs.push_back(3);//元素累计总和int num = accumulate(vs.begin(),vs.end(),0);cout << num << endl;
}
void fun17()
{vector<int> vs;vs.resize(10);//容器前5个位置填充10fill(vs.begin(),vs.end()-5,10);for_each(vs.begin(),vs.end(),[](int v){cout << v << " ";});cout << endl;
}//12
//--------------
//10 10 10 10 10 0 0 0 0 0
5.6 集合算法
/*
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, iteratorend2, 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 fun18()
{vector<int> ns1;ns1.push_back(1);ns1.push_back(3);ns1.push_back(5);ns1.push_back(7);ns1.push_back(9);vector<int> ns2;ns2.push_back(7);ns2.push_back(9);ns2.push_back(11);ns2.push_back(13);//求交集
// set<int> s;
// vector<int>::iterator it1 = ns1.begin();
// for(;it1 != ns1.end();it1++)
// {
// vector<int>::iterator it2 = ns2.begin();
// for(;it2 != ns2.end();it2++)
// {
// if(*it1 == *it2)
// {
// s.insert(*it1);
// }
// }
// }vector<int> s;set_intersection(ns1.begin(),ns1.end(),ns2.begin(),ns2.end(),back_inserter(s));for_each(s.begin(),s.end(),[](int v){cout << v << " ";});cout << endl;
}
//并集
void fun19()
{vector<int> ns1;ns1.push_back(1);ns1.push_back(3);ns1.push_back(5);ns1.push_back(7);ns1.push_back(9);vector<int> ns2;ns2.push_back(7);ns2.push_back(9);ns2.push_back(11);ns2.push_back(13);vector<int> s;set_union(ns1.begin(),ns1.end(),ns2.begin(),ns2.end(),back_inserter(s));for_each(s.begin(),s.end(),[](int v){cout << v << " ";});cout << endl;
}
//差集
void fun20()
{vector<int> ns1;ns1.push_back(1);ns1.push_back(3);ns1.push_back(5);ns1.push_back(7);ns1.push_back(9);vector<int> ns2;ns2.push_back(7);ns2.push_back(9);ns2.push_back(11);ns2.push_back(13);vector<int> s;//1对2取差集//set_difference(ns1.begin(),ns1.end(),ns2.begin(),ns2.end(),back_inserter(s));//2对1取差集set_difference(ns2.begin(),ns2.end(),ns1.begin(),ns1.end(),back_inserter(s));for_each(s.begin(),s.end(),[](int v){cout << v << " ";});cout << endl;
}//7 9
//--------------
//1 3 5 7 9 11 13
//--------------
//11 13