重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象,也叫仿函数(functor), 其实就是 重载“()”操作符
,使得 类对象 可以 像函数 那样调用。
作用:为算法提供策略。
注意:
- 函数对象(仿函数)是一个类,不是一个函数。
- 函数对象(仿函数)重载了”() ”操作符使得它可以像函数一样调用。
一元仿函数(unary_functor): 重载的 operator()要求获取一个参数
二元仿函数(binary_functor): 重载的operator()要求获取两个参数
#include
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); //4
add01(4,5); //9
//匿名对象
Add()(5,6); //11
return 0;
}
【小结】:
1、函数对象通常不定义构造函数和析构函数,所以在构造和析构时不会发生任何问题,避免了函数调用的运行时问题。
2、函数对象超出普通函数的概念,函数对象可以有自己的状态
3、函数对象可内联编译、性能好,用函数指针几乎不可能
4、模版函数对象使函数对象具有通用性,这也是它的优势之一
谓词是 指 普通函数
或 重载的 operator()
返回值是 bool 类型的函数对象(即仿函数),依据函数接收的参数又分为 一元谓词
和 二元谓词
等,谓词可作为一个判断式。
如:
gt 大于, ge 大于等于, lt小于, le小于等于, eq 等于, ne 不等于
示例:
#include
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;
}
引入头文件
#include
STL 内建了一些函数对象, 分为 算数类函数对象
、关系运算类函数对象
、逻辑运算类仿函数
等。这些仿函数所产生的对象,用法和一般函数完全相同,当然我们还可以产生无名的临时对象来履行函数功能。
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
using namespace std;
void fun01()
{
/*
template T plus//加法仿函数
template T minus//减法仿函数
template T multiplies//乘法仿函数
template T divides//除法仿函数
template T modulus//取模(取余)仿函数
template T negate//取反仿函数
*/
int num01 = plus<int>()(1,5);
cout << num01 << endl; //6
plus<int> pl;
int num02 = pl(2,6);
cout << num02 << endl; //8
cout << minus<double>()(5,1) << endl; //4
cout << multiplies<double>()(5,2) << endl; //10
cout << divides<int>()(5,2) << endl; //2
cout << modulus<int>()(5,2) << endl; //1
cout << negate<int>()(5) << endl; //-5
cout << 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;
}
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 bool equal_to//等于
template bool not_equal_to//不等于
template bool greater//大于
template bool greater_equal//大于等于
template bool less//小于
template bool less_equal//小于等于
*/
cout << equal_to<int>()(10,10) << endl; //1
cout << equal_to<int>()(10,1) << endl; //0
cout << not_equal_to<int>()(10,1) << endl; //1
cout << greater<int>()(10,1) << endl; //1
cout << greater_equal<int>()(10,1) << endl; //1
cout << greater_equal<int>()(10,10) << endl; //1
cout << greater_equal<int>()(10,11) << endl; //0
cout << less<int>()(10,1) << endl; //0
cout << less_equal<int>()(10,11) << endl; //1
}
示例2:应用于比较
#include
using namespace std;
#include
#include
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
template<class T> bool logical_and<T>//逻辑与
template<class T> bool logical_or<T>//逻辑或
template<class T> bool logical_not<T>//逻辑非
3个逻辑运算类运算函数,not 为一元谓词,其余为二元谓词。
绑定:
bind2nd将绑定的数据放置第二个参数位置
bind1st将绑定的数据放置第一个参数位置
bind1st和bind2nd 将二元函数对象转为一元函数对象
现在我有这个需求 在遍历容器的时候,我希望将容器中的值全部加上 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
将
普通函数地址
作为适配器
- 应用 ptr_fun(函数名)
- 【注意】仿函数的参数不能使用引用
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
将
函数对象
作为适配器。
for_each(v.begin(), v.end(), bind1st(函数对象类(), x));
for_each(v.begin(), v.end(), bind2nd(函数对象类(), x));
1、创建一个类,使其公共继承
binary_function
,并进行参数萃取
- 参数萃取:
- 模板中第一个类型
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
- 将
成员函数地址
作为适配器- mem_fun_ref(&类名::函数名)
本月所有员工工资加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
1)定义 unary_function
的函数对象类
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);
//查找30
vector<int>::iterator it = find(nums.begin(),nums.end(),30);
cout << (*it) << endl;
//查找大于30
vector<int>::iterator it02 = find_if(nums.begin(),nums.end(),bind2nd(greater<int>(),30));
cout << (*it02) << endl;
//查找小于30
vector<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
#include
#include
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
算法中常用的功能涉及到比较、交换、查找、遍历、复制,修改,反转,排序,合并等。
引入头文件
#include
语法:
/*
遍历算法 遍历容器元素
@param beg 开始迭代器
@param end 结束迭代器
@param _callback 函数回调或者函数对象
@return 函数对象
*/
for_each(iterator beg, iterator end, _callback);
示例1:遍历普通类型
#include
#include
#include
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 50
int 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
将指定容器区间元素 搬运
到另一容器中。
【注意】不会给目标容器分配内存,所以需要我们 提前分配好内存
语法:
/*
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
作用:查找
语法:
/*
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
作用:条件查找
/*
@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
作用:查找相邻重复元素
/**
*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
作用:二分查找 (必须有序)
/*
注意: 在无序序列中不可用
@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
作用:统计
/*
@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
作用:条件统计
/*
@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
/*
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
#include
#include
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
/*
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
/*
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个位置填充10
fill(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
/*
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 s;
// vector::iterator it1 = ns1.begin();
// for(;it1 != ns1.end();it1++)
// {
// vector::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