1.STL——函数对象
1.1 函数对象概念
1> 重载函数调用操作符的类,其对象被称为函数对象。
2> 函数对象使用重载的()时,行为类似函数调用,也叫仿函数。
本质:函数对象(仿函数)是一个类,不是一个函数。
1.2 函数对象使用
特点:
1> 函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值。
2> 函数对象存超出普通函数的概念,函数对象可以有自己的状态。
3> 函数对象可以作为参数传递。
class MyAdd
{
public:
int operator()(int a, int b)
{
return a + b;
}
};
class MyPrintf
{
public:
MyPrintf()
{
this->count = 0;
}
void operator()(string str)
{
cout << str << endl;
count++;
}
int count; //记录调用多少次
};
void test37(MyPrintf &p, string str)
{
p(str);
}
void test36()
{
MyAdd add;
//函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值。
cout << "3+5=" << add(3, 5) << endl;
MyPrintf myprintf;
myprintf("hello c++");
myprintf("hello c++");
myprintf("hello c++");
//函数对象存超出普通函数的概念,函数对象可以有自己的状态。
cout << "myprintf调用了" << myprintf.count << "次!" << endl;
//函数对象可以作为参数传递。
test37(myprintf, "hello world!");
}
1.3谓词概念
1> 返回bool类型的仿函数称为谓词。
2> 如果operator()接受一个参数,那么叫做一元谓词。
3> 如果operator()接受两个参数,那么叫做二元谓词。
一元谓词
class GreaterThree
{
public:
bool operator()(int a)
{
return a > 3;
}
};
void test38()
{
vector<int> v;
for (int i = 0; i < 5; i++)
{
v.push_back(i);
}
//GreaterThree()匿名对象
vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterThree());
if(it!=v.end())
{
cout << "找到比三大的数!" << endl;
}
}
二元谓词
class MyComp
{
public:
bool operator()(int a, int b)
{
return a > b;
}
};
void test39()
{
vector<int> v;
v.push_back(8);
v.push_back(2);
v.push_back(5);
v.push_back(1);
v.push_back(9);
cout << "v:";
VecPrintf(v); //该函数在vector那一节里面实现过
cout << "从小到大!";
sort(v.begin(), v.end());
cout << "v:";
VecPrintf(v);
cout << "从大到小!";
sort(v.begin(), v.end(), MyComp());
cout << "v:";
VecPrintf(v);
}
1.4内建函数对象
概念:STL内建了一些函数对象。
分类:
1> 算术仿函数
2> 关系仿函数
3> 逻辑仿函数
用法:
1> 这些仿函数所产生的对象,用法和一般函数完全相同
2>使用内建函数对象,需要引入头文件#include< functional >
1.5 算术仿函数:
功能:实现四则运算,其中negate是一元运算,其他为二元运算。
仿函数的函数原型:
1> template< class T> T plus< T > //加法仿函数
2> template< class T> T minus< T > //减法仿函数
3> template< class T> T multiplies< T > //乘法仿函数
4> template< class T> T divides< T > //除法仿函数
5> template< class T> T modulus< T > //取模仿函数
6> template< class T> T negate< T > //取反仿函数
void test40()
{
plus<int> p;
cout << "5+8=" << p(5, 8) << endl;
negate<int> n;
cout << "给6取反:" << n(6) << endl;
}
1.6关系仿函数
功能:实现关系对比
仿函数原型:
1> tempalte< class T > bool equal_to < T > //等于
2> template< class T > bool not_equal_to< T > //不等于
3> template< class T > bool greater< T > //大于
4> tempalte< class T > bool greater_equal< T > //大于等于
5> template< class T > bool less< T > //小于
6> template< class T > bool less_equal< T > //小于等于
其中大于用的最多
void test41()
{
vector<int> v;
v.push_back(8);
v.push_back(2);
v.push_back(5);
v.push_back(1);
v.push_back(9);
cout << "v:";
VecPrintf(v); //该函数在vector那一节里面实现过
cout << "从小到大!";
sort(v.begin(), v.end());
cout << "v:";
VecPrintf(v);
cout << "从大到小!";
sort(v.begin(), v.end(), greater<int>());
cout << "v:";
VecPrintf(v);
}
1.7 逻辑仿函数
功能:实现逻辑运算
仿函数原型:
1> template< class T > bool logical_and< T > //逻辑与
2> template< class T > bool logical_or< T > //逻辑或
3> template< class T > bool logical_not< T > //逻辑非
基本上用不到
void test42()
{
vector<bool> v;
v.push_back(true);
v.push_back(false);
v.push_back(false);
v.push_back(true);
v.push_back(false);
cout << "V:";
for (vector<bool>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it;
}
cout << endl;
vector<bool> v1;
//必须要先给v1开辟空间,不然transform无法将v的元素搬运到v1
v1.resize(v.size());
transform(v.begin(), v.end(), v1.begin(), logical_not<bool>());
cout << "V1:";
for (vector<bool>::iterator it = v1.begin(); it != v1.end(); it++)
{
cout << *it;
}
}
2.STL——常用算法
2.1 概述:
1> 算法主要是由头文件< algorithm >、< functional >、< numeric >组成。
2> < algorithm >是所有STL头文件中最大的一个,范围涉及到比较、交换、查找、遍历操作、复制、修改等等。
3> < numeric >体积很小,只包括几个在序列上面进行简单数学运算的模板函数。
4> < functional > 定义了一些模板类,用以声明函数对象。
2.2 常用遍历算法
目标:掌握常用的遍历算法。
1> for_each
2> transform
注意:for_each后面用函数名与函数对象都可以
算法简介:
1> for_each //遍历容器 (非常常用,必须掌握)
class MyPrintf
{
public:
void operator()(int a)
{
cout << a << " ";
}
};
void print(int a)
{
cout << a << " ";
}
void test()
{
vector<int> v(6, 8);
//使用普通函数
for_each(v.begin(), v.end(), print);
cout << endl;
//使用仿函数
for_each(v.begin(), v.end(), MyPrintf());
cout << endl;
}
2> transform
功能:搬运容器到另一个容器中。
函数原型:
transform(iterator beg1, iterator end1, iterator beg2, _func)
//beg1 源容器开始迭代器
//end1 原容器结束迭代器
//beg2 目标容器开始迭代器
//_func 函数或者函数对象
注意:_func函数名或者函数对象都可以,而且for_each也是如此。至于前面用到过加法函数对象里面有参数是因为,先创建了对象,对象后面跟的参数是重载(),相当于函数了。这里是使用的类名()就是使用匿名对象,即使重载()里有参数这里也不写参数,这里是创建函数对象,相当于普通函数的函数名,所以无论是for_each还是transform后面写函数对象与写普通函数的函数名效果一样。
void print(int a)
{
cout << a << " ";
}
class Trans
{
public:
int operator()(int v)
{
return v+10;
}
};
int Transform(int v)
{
return v+10;
}
void test1()
{
vector<int> v; //源容器
cout << "v:";
for (int i = 0; i < 5; i++)
{
v.push_back(i);
}
for_each(v.begin(), v.end(), print);
cout << endl;
vector<int> v1; //目标容器
v1.resize(v.size());
//这里Trans()里面没填参数是因为这里是函数对象,使用匿名对象
//简单说,把构造函数、重载()操作符、成员函数、函数对象等理清即可
transform(v.begin(), v.end(), v1.begin(), Trans());
cout << "v1:";
for_each(v1.begin(), v1.end(), print);
cout << endl;
vector<int> v2;
v2.resize(v.size());
//这里Trans()与Transform效果一样,后者是函数名,前者是函数对象,需要理清楚
transform(v1.begin(), v1.end(), v2.begin(), Transform);
cout << "v2:";
for_each(v2.begin(), v2.end(), print);
cout << endl;
}
2.3 常用查找算法
目标:掌握常用的查找算法
算法简介:
1> find //查找元素
2> find_if //按照条件查找元素
3> adjacent_find //查找相邻重复元素
4> binary_search //二分查找
5> count //统计元素个数
6> count_if //按照条件统计元素个数
1> find
功能:查找指定元素,找到返回指向该元素的指针,找不到返回结束迭代器end()。
函数原型:
find(iterator beg, iterator end, value);
void print(int a)
{
cout << a << " ";
}
//使用find查找自定义数据类型
class Person
{
public:
Person(string name, int age) :m_Name(name), m_Age(age) {
}
bool operator==(const Person &p)
{
if (this->m_Age == p.m_Age&&this->m_Name == p.m_Name)
{
return true;
}
else
{
return false;
}
}
string m_Name;
int m_Age;
};
//print1函数用于输出Person
void print1(const Person &p)
{
cout << "姓名:" << p.m_Name << " 年龄:" << p.m_Age << endl;
}
void test()
{
vector<int> v;
for (int i = 0; i < 5; i++)
{
v.push_back(i);
}
cout << "v:";
for_each(v.begin(), v.end(), print);
cout << endl;
//查找元素3
vector<int>::iterator it = find(v.begin(), v.end(), 3);
if (it != v.end())
{
cout << "找到元素3!" << endl;
}
else
{
cout << "找不到元素3" << endl;
}
cout << "使用find查找自定义数据类型!" << endl;
string PartName = "abcde";
vector<Person> v1;
for (int i = 0; i < 3; i++)
{
string name = "Person ";
name += PartName[i];
int age = 15;
age += i;
Person p(name, age);
v1.push_back(p);
}
cout << "v1:" << endl;
for_each(v1.begin(), v1.end(), print1);
Person p0("Person j", 15);
//查找元素p
//运行报错,通过看find函数的定义我们发现底层判断是*__first == __value_;很显然自定义数据数据类型无法直接比较
//所以Person需要重载==操作符
vector<Person>::iterator pit = find(v1.begin(), v1.end(), p0);
if (pit == v1.end())
{
cout << "找不到元素p!" << endl;
}
else
{
cout << "找到元素p" << " 姓名为:" << pit->m_Name << " 年龄为:" << pit->m_Age << endl;
}
}
值得注意的是如果查找的是自定义数据类型,需要重载== 操作符,具体要看函数定义。通过看find函数的定义我们发现底层判断是 (*__first) == __value _;很显然自定义数据数据类型无法直接比较。所以Person需要重载==操作符
2>find_if
功能:按条件查找元素
函数原型:
find_if(iterator beg, iterator end, _Pred);
//按照条件查找元素,找到返回指定位置的迭代器,找不到返回结束迭代器位置
//beg开始迭代器
//end结束迭代器
//_Pred 函数名或者谓词(返回bool类型的仿函数)
class GreaterFive
{
public:
bool operator()(int v)
{
return v > 5;
}
};
void test()
{
vector<int> v;
for (int i = 0; i < 5; i++)
{
v.push_back(i);
}
vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());
if (it == v.end())
{
cout << "找不到大于5的元素!" << endl;
}
else
{
cout << "找到大于5的元素!" << endl;
}
}
//find_if 自定义类型
class Person
{
public:
Person(string name, int age) :m_Name(name), m_Age(age) {
}
string m_Name;
int m_Age;
};
class FindAge
{
public:
bool operator()(const Person &p)
{
return p.m_Age == 16;
}
};
void test1()
{
vector<Person> v;
string PartName = "ABCDE";
for (int i = 0; i < 5; i++)
{
string name = "Student";
name += PartName[i];
int age = 15 + i;
Person p(name, age);
v.push_back(p);
}
cout << "查找年龄为16的学生!" << endl;
vector<Person>::iterator it = find_if(v.begin(), v.end(), FindAge());
if (it == v.end())
{
cout << "没找到!" << endl;
}
else
{
cout << "找到了,姓名为:" << it->m_Name << endl;
}
}
3> adjacent_find
功能:查找相邻重复元素
函数原型:
adjacent_find(iterator beg, iterator end);
//查找相邻重复元素,返回相邻元素的第一个位置的迭代器
//beg 开始迭代器
//end 结束迭代器
注意:一般实际开发中用的不多,可能面试会用到。
void test()
{
vector<int> v;
v.push_back(0);
v.push_back(3);
v.push_back(0);
v.push_back(7);
v.push_back(5);
v.push_back(5);
v.push_back(8);
vector<int>::iterator it = adjacent_find(v.begin(), v.end());
cout << "v中第一个重复元素为:" << *it << endl;
}
4> binary_search
功能:查找指定元素是否存在
函数原型:bool binary_search(iterator beg, iterator end, value);
//查找指定的元素,找到返回ture,否则返回false。
//beg开始迭代器
//end结束迭代器
//value 查找的元素
注意:无序序列中不可使用
void test()
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
if (binary_search(v.begin(), v.end(), 8))
{
cout << "找到元素8" << endl;
}
else
{
cout << "没找到元素8" << endl;
}
}
5> count
功能:统计元素个数
函数原型:
count(iterator beg, iterator end, value);
//统计元素出现的次数
//beg开始迭代器
//end结束迭代器
//value统计的元素
//统计内置数据类型
注意:如果要对自定义数据类型的容器进行计数便要重载==,与前面一致,还是去看看count函数的底层实现,发现依然用到了 ==进行比较。
void test()
{
vector<int> v;
v.push_back(0);
v.push_back(3);
v.push_back(0);
v.push_back(7);
v.push_back(5);
v.push_back(5);
v.push_back(8);
cout << "元素0出现次数:" << count(v.begin(), v.end(), 0) << endl;
}
//统计自定义数据类型
class Person
{
public:
Person(string name, int age) :m_Name(name), m_Age(age) {
}
bool operator==(const Person &p)
{
if (this->m_Age == p.m_Age)
{
return true;
}
else
{
return false;
}
}
string m_Name;
int m_Age;
};
void test1()
{
vector<Person> v;
Person p1("张三", 16);
Person p2("李四", 16);
Person p3("王五", 17);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
int num = count(v.begin(), v.end(), p2);
cout << "与李四同岁的一共有" << num << "人!" << endl;
}
6> count_if
功能:按条件统计元素个数
函数原型:
count_if(iterator beg, iterator end, _Pred);
//按条件统计元素出现次数
//beg开始迭代器
//end结束迭代器
//_Pred 谓词或者普通函数函数名
class GreaterTwo
{
public:
bool operator()(int v)
{
return v > 2;
}
};
bool greaterTwo(int v)
{
return v > 2;
}
void test()
{
vector<int> v;
for (int i = 0; i < 5; i++)
{
v.push_back(i);
}
int num = count_if(v.begin(), v.end(), greaterTwo);
cout << "大于2的有:" << num << "个" << endl;
}
class Person
{
public:
Person(string name, int age) :m_Name(name), m_Age(age) {
}
string m_Name;
int m_Age;
};
class AgeGreater17
{
public:
bool operator ()(const Person &p)
{
return p.m_Age > 17;
}
};
bool ageGreater16(const Person &p)
{
return p.m_Age > 16;
}
void test1()
{
vector<Person> v;
Person p1("张三", 16);
Person p2("李四", 16);
Person p3("王五", 17);
Person p4("张飞", 19);
Person p5("刘备", 18);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
int num = count_if(v.begin(), v.end(), ageGreater16);
cout << "年龄大于16有" << num << "人" << endl;
}
2.4 常用排序算法
目标:掌握常用的排序算法
算法简介:
1> sort; //对容器内的元素进行排序
2>random_shuffle;//洗牌,指定范围内的元素随机调整次序
3>merge;//容器元素合并,并存储到同一容器中
4>reverse; //反转指定范围的元素
1> sort
功能描述:对容器内元素进行排序
函数原型:
sort(iterator beg, iterator end, _Pred);
//按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器
//beg 开始迭代器
//end 结束迭代器
//_Pred 谓词或者普通函数函数名
void print(int v)
{
cout << v << " ";
}
void test()
{
vector<int> v;
for (int i = 10; i > 0; i--)
{
v.push_back(i);
}
cout << "V:";
for_each(v.begin(), v.end(), print);
//这里sort默认升序排列,如果加入一些STL内建的函数对象,比如greater<int>()
//template< class T > bool greater< T > //大于
sort(v.begin(), v.end());
cout << "使用sort排序后!" << endl;
cout << "V:";
for_each(v.begin(), v.end(), print);
}
注意:sort是开发中最常用的算法之一,必须掌握
2> random_shuffle
功能:洗牌,指定范围内的元素随机调整次序
函数原型:
random_shuffle(iterator beg, iterator end);
//指定范围内的元素进行随机调整次序
//beg 开始迭代器
//end 结束迭代器
void print(int v)
{
cout << v << " ";
}
void test()
{
vector<int> v;
for (int i = 10; i > 0; i--)
{
v.push_back(i);
}
cout << "V:";
for_each(v.begin(), v.end(), print);
cout << endl;
random_shuffle(v.begin(), v.end());
cout << "使用random_shuffle打乱排序后!" << endl;
cout << "V:";
for_each(v.begin(), v.end(), print);
}
注意:random_shuffle洗牌算法还是比较实用的,使用时记得加上随机种子。
3> merge
功能:两个容器元素合并,并存储到另一个容器中。
注意:两元素必须有序(且都是升序),而且合并后依然有序,并且目标容器在合并前要resize
函数原型:
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//容器元素合并,并存储到另一个容器中
//beg1 容器1开始迭代器
//end1 容器1结束迭代器
//beg2 容器2开始迭代器
//end2 容器2结束迭代器
//dest 目标容器的开始迭代器
void print(int v)
{
cout << v << " ";
}
void test()
{
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
cout << "V1:";
for_each(v1.begin(), v1.end(), print);
cout << endl;
vector<int> v2;
for (int i = 5; i < 10; i++)
{
v2.push_back(i);
}
cout << "v2:";
for_each(v2.begin(), v2.end(), print);
cout << endl;
cout << "使用merge合并排序后!" << endl;
vector<int> v;
v.resize(20);
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v.begin());
cout << "V:";
for_each(v.begin(), v.end(), print);
}
4> reverse
功能:将容器内的元素进行反转。
函数原型:
reverse(iterator beg, iterator end);
//反转指定范围内的元素
//beg 开始迭代器
//end 结束迭代器
void print(int v)
{
cout<<v<<" ";
}
void test()
{
vector<int> v;
for(int i = 0;i<10;i++)
{
v.push_back(i);
}
cout<<"v:";
for_each(v.begin(), v.end(), print);
cout<<"使用reverse反转后!"<<endl;
reverse(v.begin(), v.end());
cout<<"v:";
for_each(v.begin(), v.end(), print);
}
2.5 常用拷贝和替换算法
目的:学习掌握拷贝和替换算法
算法简介:
1> copy 容器内指定范围内的元素拷贝到另一个容器中
2> replace 将容器内指定范围的旧元素修改成新元素
3> replace_if 将容器内指定范围内的符合条件的旧元素修改成新元素
4> swap 互换两容器内的元素
1> copy
功能:将容器内指定范围的元素拷贝到另一个容器中
函数原型:
copy(iterator beg, iterator end, iterator dest);
//将容器内指定范围内的元素拷贝到另一个容器中
//beg:开始迭代器
//end:结束迭代器
//dest:目标迭代器的开始迭代器
注意:这里使用copy之前对目标容器要使用resize函数开辟空间,此函数一般实际开发中使用不多。
void print(int i)
{
cout<<i<<" ";
}
void test()
{
vector<int> v;
for(int i=0;i<10;i++)
{
v.push_back(i);
}
cout<<"v:";
for_each(v.begin(), v.end(), print);
cout<<endl;
cout<<"v1使用copy,复制v!"<<endl;
vector<int> v1;
v1.resize(10);
copy(v.begin(), v.end(), v1.begin());
cout<<"v1:";
for_each(v1.begin(), v1.end(), print);
cout<<endl;
}
2> replace
功能:将容器内指定范围内的元素替换成新元素
函数原型:
replace(iterator beg, iterator end, oldvalue, newvalue);
//指定范围内的元素替换成新元素
//beg 开始迭代器
//end 结束迭代器
//oldvalue 旧元素
//newvalue 新元素
void print(int i)
{
cout<<i<<" ";
}
void test()
{
vector<int> v;
for(int i=0;i<10;i++)
{
v.push_back(i);
}
cout<<"v:";
for_each(v.begin(), v.end(), print);
cout<<endl;
cout<<"把5替换成35"<<endl;
replace(v.begin(), v.end(), 5, 35);
cout<<"v:";
for_each(v.begin(), v.end(), print);
cout<<endl;
}
3> replace_if
功能:将容器内指定范围内的所有符合条件的元素替换成新元素
函数原型:
replace_if(iterator beg, iterator end, _ Pred, newvalue);
//把范围内所有符合条件的元素用新元素替换
//beg 开始迭代器
//end 结束迭代器
//_ Pred 谓词或者函数名
//newvalue 替换的新元素
void print(int i)
{
cout<<i<<" ";
}
bool Greater5(int a)
{
return a>5;
}
void test()
{
vector<int> v;
for(int i=0;i<10;i++)
{
v.push_back(i);
}
cout<<"v:";
for_each(v.begin(), v.end(), print);
cout<<endl;
cout<<"把大于5的都替换成30"<<endl;
replace_if(v.begin(), v.end(), Greater5, 30);
cout<<"v:";
for_each(v.begin(), v.end(), print);
cout<<endl;
}
4>swap
功能:互换两容器的元素
注意:一定要两种同等类型的容器
函数原型:
swap(container c1, container c2);
//互换两容器的元素
//c1,容器1
//c2,容器2
void print(int i)
{
cout<<i<<" ";
}
void test()
{
vector<int> v1;
vector<int> v2;
for(int i=0;i<10;i++)
{
v1.push_back(i);
v2.push_back(i+5);
}
cout<<"v1:";
for_each(v1.begin(), v1.end(), print);
cout<<endl;
cout<<"v2:";
for_each(v2.begin(), v2.end(), print);
cout<<endl;
cout<<"使用swap交换后!"<<endl;
swap(v1, v2);
cout<<"v1:";
for_each(v1.begin(), v1.end(), print);
cout<<endl;
cout<<"v2:";
for_each(v2.begin(), v2.end(), print);
cout<<endl;
}
2.6 常用算术生成算法
目标:学习掌握常用的算术生成算法。
注意:算术生成算法属于小型算法,使用需要包含头文件#include< numeric >
算法简介:
1> accumulate; 计算容器元素累计总和
2> fill; //向容器中添加新元素
1> accumulate
功能:计算区间内容器元素累计总和
函数原型:
accumulate(iterator beg, iterator end, value);
//计算区间内容器元素累计总和
//beg 开始迭代器
//end 结束迭代器
//value 起始值
void print(int i)
{
cout<<i<<" ";
}
void test()
{
vector<int> v;
for(int i=0;i<10;i++)
{
v.push_back(i);
}
cout<<"v:";
for_each(v.begin(), v.end(), print);
cout<<endl;
cout<<"元素总和为:";
int total = accumulate(v.begin(), v.end(), 0);
cout<<total<<endl;
}
该算法比较常用
2> fill
功能:向容器中添加新元素。
注意:这里的填充,即使区间内有初始值也被换成填充值。
函数原型:
fill(iterator beg, iterator end, value);
//向容器中添加新元素
//beg 开始迭代器
//end 结束迭代器
//value 填充的值
void print(int i)
{
cout<<i<<" ";
}
void test()
{
vector<int> v;
for(int i=0;i<10;i++)
{
v.push_back(i);
}
v.resize(15);
fill(v.begin(), v.end(), 100);
cout<<"v:";
for_each(v.begin(), v.end(), print);
cout<<endl;
//v:100 100 100 100 100 100 100 100 100 100 100 100 100 100 100
}
2.7 常用集合算法
目标:掌握常用的集合算法
算法简介:
1> set_intersection //求两个容器的交集
2> set_union //求两个容器的并集
3> set_difference //求两个容器的差集
1> set_intersection
功能:求两个容器的交集
函数原型:
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
注意:返回的是指向交集最后一个元素的下一位的迭代器
//求两个容器的交集
//beg1 容器1开始迭代器
//end1 容器1结束迭代器
//beg2 容器2开始迭代器
//end2 容器2结束迭代器
//dest 目标容器的开始迭代器
void print(int v)
{
cout << v << " ";
}
void test()
{
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
cout << "V1:";
for_each(v1.begin(), v1.end(), print);
cout << endl;
vector<int> v2;
for (int i = 5; i < 15; i++)
{
v2.push_back(i);
}
cout << "v2:";
for_each(v2.begin(), v2.end(), print);
cout << endl;
cout << "使用set_intersection求交集后!" << endl;
vector<int> v;
v.resize(min(v1.size(),v2.size()));
vector<int>::iterator it = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), v.begin());
cout << "V:";
//这里如果使用end的话,便会把所有元素都输出出来,显然容器的大小是大于等于交集大小的,那剩余部分由0填充。
//for_each(v.begin(), v.end(), print);
//cout << endl;
for_each(v.begin(), it, print);
}
2> set_union
功能:求两个集合的并集
注意:两个集合必须是有序序列,必须是升序
函数原型:
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//求两个集合的并集
//beg1 容器1开始迭代器
//end1 容器1结束迭代器
//beg2 容器2开始迭代器
//end2 容器2结束迭代器
//dest 目标容器的开始迭代器
void print(int v)
{
cout << v << " ";
}
void test()
{
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
cout << "V1:";
for_each(v1.begin(), v1.end(), print);
cout << endl;
vector<int> v2;
for (int i = 5; i < 15; i++)
{
v2.push_back(i);
}
cout << "v2:";
for_each(v2.begin(), v2.end(), print);
cout << endl;
cout << "使用set_union求并集后!" << endl;
vector<int> v;
v.resize(v1.size()+v2.size());
vector<int>::iterator it = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), v.begin());
cout << "V:";
//这里如果使用end的话,便会把所有元素都输出出来,显然容器的大小是大于等于交集大小的,那剩余部分由0填充。
//for_each(v.begin(), v.end(), print);
//cout << endl;
for_each(v.begin(), it, print);
}
3> set_difference
注意:这里哪个容器在前就在哪个容器的基础上求差集。例如v1{1,2,3} v2{3,4,5}如果v1在前求出便是v{1,2},反之v{4,5}.所以这里关于目标容器的大小就直接按照max(v1.size(), v2.size())
函数原型:
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//求v1和v2的差集
//beg1 容器v1开始迭代器
//end1 容器v1结束迭代器
//beg2 容器v2开始迭代器
//end2 容器v2结束迭代器
//dest 目标容器的开始迭代器
void print(int v)
{
cout << v << " ";
}
void test()
{
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
cout << "V1:";
for_each(v1.begin(), v1.end(), print);
cout << endl;
vector<int> v2;
for (int i = 5; i < 15; i++)
{
v2.push_back(i);
}
cout << "v2:";
for_each(v2.begin(), v2.end(), print);
cout << endl;
cout << "使用set_difference求交集后!" << endl;
vector<int> v3;
v3.resize(max(v1.size(), v2.size()));
vector<int>::iterator it1 = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());
cout << "v1和v2的差集:";
//这里如果使用end的话,便会把所有元素都输出出来,显然容器的大小是大于等于交集大小的,那剩余部分由0填充。
//for_each(v.begin(), v.end(), print);
//cout << endl;
for_each(v3.begin(), it1, print);
cout << endl;
vector<int> v4;
v4.resize(max(v1.size(), v2.size()));
vector<int>::iterator it2 = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), v4.begin());
cout << "v2和v1的差集:";
//这里如果使用end的话,便会把所有元素都输出出来,显然容器的大小是大于等于交集大小的,那剩余部分由0填充。
//for_each(v.begin(), v.end(), print);
//cout << endl;
for_each(v4.begin(), it2, print);
}