文章目录
- 56、STL六大组件之遍历算法
- 57、STL六大组件之查找算法1
- 58、STL六大组件之查找算法2
- 59、STL六大组件之统计算法
- 60、STL六大组件之合并算法
- 61、随机数(rand)和随机数种子(srand)的理解
- 62、STL六大组件之随机算法(洗牌算法)
- 63、STL六大组件之排序算法和反转算法
- 64、STL六大组件之拷贝算法和替换算法
- 65、STL六大组件之算术生成算法和填充算法
- 66、STL六大组件之集合算法
56、STL六大组件之遍历算法
/*
#include<algorithm> 算法
#include<functional> 函数对象
#include<numbers> 算法补充
通过迭代器来操作容器中的元素
for_each(begin(),end(),callback);遍历容器算法,将迭代器指向的元素当参数来调用普通函数或者函数对象或者lambda表达式,
返回值为回调函数
transform(begin1(),end1(),begin2(),callback)将指定容器区间的元素搬到另一个容器
不会给目标容器预先分配内存,要手动预先分配好内存
operator2 transform(begin1(),end1(),begin2(),callback)
begin1() 原容器开始迭代器
end1() 原容器结束迭代器
begin2() 目标容器开始迭代器
callback 回调函数,可以是普通函数,函数对象(仿函数),lambda表达式
operator2 返回目标容器的特定位置迭代器
operator3 transform(begin1(),end1(),begin2(),begin3(),callback)
begin1() 原容器开始迭代器
end1() 原容器结束迭代器
begin2() 目标容器开始迭代器
begin3() 目标容器开始迭代器
callback 回调函数,可以是普通函数,函数对象(仿函数),lambda表达式
operator3 返回目标容器的特定位置迭代器
*/
代码如下:
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
/*
#include<algorithm> 算法
#include<functional> 函数对象
#include<numbers> 算法补充
通过迭代器来操作容器中的元素
for_each(begin(),end(),callback);遍历容器算法,将迭代器指向的元素当参数来调用普通函数或者函数对象或者lambda表达式,
返回值为回调函数
transform(begin1(),end1(),begin2(),callback)将指定容器区间的元素搬到另一个容器
不会给目标容器预先分配内存,要手动预先分配好内存
operator2 transform(begin1(),end1(),begin2(),callback)
begin1() 原容器开始迭代器
end1() 原容器结束迭代器
begin2() 目标容器开始迭代器
callback 回调函数,可以是普通函数,函数对象(仿函数),lambda表达式
operator2 返回目标容器的特定位置迭代器
operator3 transform(begin1(),end1(),begin2(),begin3(),callback)
begin1() 原容器开始迭代器
end1() 原容器结束迭代器
begin2() 目标容器开始迭代器
begin3() 目标容器开始迭代器
callback 回调函数,可以是普通函数,函数对象(仿函数),lambda表达式
operator3 返回目标容器的特定位置迭代器
*/
//普通函数
void MyPrint(std::string& str){
std::cout<<str<<" ";
}
//函数对象仿函数
class Print{
public:
void operator()(std::string& str){
std::cout<<str<<" ";
}
};
void Func1(){
std::vector<std::string> vec1{"tom","jery","rose"};
std::for_each(vec1.begin(),vec1.end(),MyPrint);
std::cout<<std::endl;
std::for_each(vec1.begin(),vec1.end(),Print());
std::cout<<std::endl;
std::for_each(vec1.begin(),vec1.end(),[&](std::string& str)->void{
std::cout<<str<<" ";
});
std::cout<<std::endl;
}
std::string& MyPrint2(std::string& str){
return str;
}
void Func2(){
std::vector<std::string> vec1{"aaa","jery","bbb"};
std::vector<std::string> vec2;
vec2.resize(vec1.size());
std::transform(vec1.begin(),vec1.end(),vec2.begin(),MyPrint2);
std::for_each(vec2.begin(),vec2.end(),[=](std::string& str)->void{
std::cout<<str<<" ";
});
std::cout<<std::endl;
std::for_each(vec2.begin(),vec2.end(),Print());
std::cout<<std::endl;
}
_Uint32t AddNum(_Uint32t a,_Uint32t b){
return a+b;
}
void Func3(){
std::vector<int> vec1{1,2,3,4};
std::vector<int> vec2{10,20,30,50};
std::vector<int> vec3;
vec3.resize(vec1.size());
std::transform(vec1.begin(),vec1.end(),vec2.begin(),vec3.begin(),AddNum);
std::for_each(vec3.begin(),vec3.end(),[&](_Uint32t a)->void{
std::cout<<a<<" ";
});
std::cout<<std::endl;
}
int main(){
Func1();
Func2();
Func3();
return 0;
}
输出结果:
PS D:\C++泛型编程与模板代码\build\bin\Debug> .\main.exe
tom jery rose
tom jery rose
tom jery rose
aaa jery bbb
aaa jery bbb
11 22 33 54
PS D:\C++泛型编程与模板代码\build\bin\Debug>
57、STL六大组件之查找算法1
/*
iterator find(begin,end,val)
iterator find_if(begin,end,func)
begin();被查找的容器的开始迭代器
end(); 被查找的容器的结束迭代器
func 查找条件的函数或者函数对象(谓词)
*/
代码如下:
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<functional>
/*
iterator find(begin,end,val)
iterator find_if(begin,end,func)
begin();被查找的容器的开始迭代器
end(); 被查找的容器的结束迭代器
func 查找条件的函数或者函数对象(谓词)
*/
void Func1(){
std::vector<int> vec1{1,2,3,4,5,6};
std::vector<int>::iterator iter1=std::find(vec1.begin(),vec1.end(),3);
if(iter1!=vec1.end()){
std::cout<<*iter1<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
auto iter2=std::find(vec1.begin(),vec1.end(),10);
if(iter2!=vec1.end()){
std::cout<<*iter2<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
}
class A{
public:
A(_Uint32t id,std::string name)
:id_(id)
,name_(name){}
bool operator==(const A& a){
return (id_==a.id_)&&(name_==a.name_);
}
_Uint32t GetId(){
return id_;
}
std::string& GetName(){
return name_;
}
private:
_Uint32t id_;
std::string name_;
};
void Func2(){
std::vector<A> vec1{A(1,"tom"),A(2,"jery")};
auto iter1=std::find(vec1.begin(),vec1.end(),A(2,"jery"));
if(iter1!=vec1.end()){
std::cout<<(*iter1).GetId()<<" "<<(*iter1).GetName()<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
}
struct MyFind1{
public:
bool operator()(_Uint32t id){
return id=3;
}
};
struct MyFind2:public std::binary_function<_Uint32t,_Uint32t,bool>{
bool operator()(_Uint32t a,_Uint32t b) const{
return a==b;
}
};
void Func3(){
std::vector<int> vec1{1,2,3,4};
auto iter1=std::find_if(vec1.begin(),vec1.end(),MyFind1());
if(iter1!=vec1.end()){
std::cout<<*iter1<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
auto iter2=std::find_if(vec1.begin(),vec1.end(),std::bind2nd(MyFind2(),2));
if(iter2!=vec1.end()){
std::cout<<*iter2<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
}
struct MyFind3{
bool operator()(A& a){
return (a.GetId()==1&&a.GetName()=="tom");
}
};
void Func4(){
std::vector<A> vec1{A(1,"tom"),A(2,"jery"),A(3,"rose")};
auto iter1=std::find_if(vec1.begin(),vec1.end(),MyFind3());
if(iter1!=vec1.end()){
std::cout<<(*iter1).GetId()<<" "<<(*iter1).GetName()<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
}
struct MyFinc4:public std::binary_function<A,A,bool>{
bool operator()(A& a1,A& a2) const{
return a1.GetId()==a1.GetId()&&a1.GetName()==a1.GetName();
}
};
void Func5(){
std::vector<A> vec1{A(1,"tom"),A(2,"jery")};
auto iter1=std::find_if(vec1.begin(),vec1.end(),std::bind2nd(MyFinc4(),A(1,"tom")));
if(iter1!=vec1.end()){
std::cout<<(*iter1).GetId()<<" "<<(*iter1).GetName()<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
}
int main(){
Func1();
Func2();
Func3();
Func4();
Func5();
return 0;
}
输出结果:
PS D:\C++泛型编程与模板代码\build\bin\Debug> .\main.exe
3
not find
2 jery
1
2
1 tom
PS D:\C++泛型编程与模板代码\build\bin\Debug>
58、STL六大组件之查找算法2
查找相邻的重复元素
iterator adjacent_find(begin(),end())
iterator adjacent_find(begin(),end(),func) func可以理解成一个函数对象
代码如下:
class A{
public:
A(_Uint32t id,std::string name)
:id_(id)
,name_(name)
{}
_Uint32t GetId(){
return id_;
}
std::string& GetName(){
return name_;
}
private:
_Uint32t id_;
std::string name_;
};
void Func1(){
std::vector<std::string> vec1{"tom","jery","jery","rose"};
std::vector<std::string>::iterator iter1=std::adjacent_find(vec1.begin(),vec1.end());
if(iter1!=vec1.end()){
std::cout<<*iter1<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
std::vector<std::string> vec2{"tom","jery","rose"};
auto iter2=std::adjacent_find(vec2.begin(),vec2.end());
if(iter2!=vec2.end()){
std::cout<<*iter2<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
}
struct MyFind1{
bool operator()(A& a,A& b){
return a.GetId()==b.GetId()&&a.GetName()==b.GetName();
}
};
void Func2(){
std::vector<A> vec1{A(1,"tom"),A(2,"jery"),A(2,"jery")};
auto iter1=std::adjacent_find(vec1.begin(),vec1.end(),MyFind1());
if(iter1!=vec1.end()){
std::cout<<(*iter1).GetId()<<" "<<(*iter1).GetName()<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
}
输出结果:
PS D:\C++泛型编程与模板代码\build\bin\Debug> .\main.exe
jery
not find
2 jery
PS D:\C++泛型编程与模板代码\build\bin\Debug>
二分查找 - 此算法在无序列容器中无法使用(就是说要先sort一下) 其实说出了二分查找需要的条件
用于查找的内容逻辑上来说是需要有序的,查找的数量只能是一个,而不是多个。
bool std::binary_search(begin(),end(),val,less<T>()) 默认函数对象升序
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<functional>
/*
查找相邻的元素
iterator adjacent_find(begin(),end());
iterator adjacent_find(begin(),end(),func);
二分查找
bool binary_search -二分查找算法首先要在有序的容器中使用,在无序的容器中要先使用sort排序
*/
class A{
public:
A(_Uint32t id,std::string name)
:id_(id)
,name_(name)
{}
_Uint32t GetId(){
return id_;
}
std::string& GetName(){
return name_;
}
//默认用的是std::less<T>()函数对象
bool operator< (A& a) const {
std::cout<<id_<<" "<<a.GetId()<<std::endl;
return id_<a.GetId();
}
bool operator >(A& a) const{
std::cout<<id_<<" "<<a.GetId()<<std::endl;
return id_<a.GetId();
}
private:
_Uint32t id_;
std::string name_;
};
void Func1(){
std::vector<std::string> vec1{"tom","jery","jery","rose"};
std::vector<std::string>::iterator iter1=std::adjacent_find(vec1.begin(),vec1.end());
if(iter1!=vec1.end()){
std::cout<<*iter1<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
std::vector<std::string> vec2{"tom","jery","rose"};
auto iter2=std::adjacent_find(vec2.begin(),vec2.end());
if(iter2!=vec2.end()){
std::cout<<*iter2<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
}
struct MyFind1{
bool operator()(A& a,A& b){
return a.GetId()==b.GetId()&&a.GetName()==b.GetName();
}
};
void Func2(){
std::vector<A> vec1{A(1,"tom"),A(2,"jery"),A(2,"jery")};
auto iter1=std::adjacent_find(vec1.begin(),vec1.end(),MyFind1());
if(iter1!=vec1.end()){
std::cout<<(*iter1).GetId()<<" "<<(*iter1).GetName()<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
}
void Func3(){
std::vector<int> vec1{1,2,3,4,5,6,7,8};
bool flag1=std::binary_search(vec1.begin(),vec1.end(),3);
if(flag1==true){
std::cout<<"find"<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
std::vector<int> vec2{1,2,5,6,3,8,7};
std::sort(vec2.begin(),vec2.end(),std::greater<int>());
std::for_each(vec2.begin(),vec2.end(),[&](_Uint32t i){
std::cout<<i<<" ";
});
std::cout<<std::endl;
//默认从std::less<T>比较
bool flag2=std::binary_search(vec2.begin(),vec2.end(),3,std::greater<int>());
if(flag2==true){
std::cout<<"find"<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
}
//从大到小排序
struct MyFind2{
bool operator()(A a,A b){
return a.GetId()>b.GetId();
}
};
void Func4(){
std::vector<A> vec1{A(1,"tom"),A(2,"jery"),A(3,"rose")};
//val 为一个类,就在类里面写个函数对象
//从小到大排序
bool flag1=std::binary_search(vec1.begin(),vec1.end(),A(1,"tom"));
if(flag1==true){
std::cout<<"find"<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
bool flag2=std::binary_search(vec1.begin(),vec1.end(),A(1,"tom"),MyFind2());
if(flag2==true){
std::cout<<"find"<<std::endl;
}else{
std::cout<<"not find"<<std::endl;
}
}
int main(){
Func1();
Func2();
Func3();
Func4();
return 0;
}
59、STL六大组件之统计算法
/*
统计val出现的次数
int std::count(begin(),end(),val)
int std::count(begin(),end(),func)
*/
代码如下:
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<functional>
/*
统计val出现的次数
int std::count(begin(),end(),val)
int std::count(begin(),end(),func)
*/
class A{
public:
A(_Uint32t id,std::string name)
:id_(id)
,name_(name)
{}
_Uint32t GetId(){
return id_;
}
std::string& GetName(){
return name_;
}
//bool operator==(const A& a){
// return (id_==a.GetId()&&name_==a.GetName());
//}
bool operator==(const A& a) {
return id_ == a.id_ && name_ == a.name_;
}
//private:
_Uint32t id_;
std::string name_;
};
void Func1(){
std::vector<std::string> vec1{"tom","jery","a","tom","a","b","a"};
_Uint32t num1=std::count(vec1.begin(),vec1.end(),"a");
std::cout<<num1<<std::endl;
_Uint32t num2=std::count(vec1.begin(),vec1.end(),"tom");
std::cout<<num2<<std::endl;
}
void Func2(){
std::vector<A> vec1{A(1,"aa"),A(2,"bb"),A(1,"aa"),A(1,"aa")};
_Uint32t num1=std::count(vec1.begin(),vec1.end(),A(1,"aa"));
std::cout<<num1<<std::endl;
}
struct MyFind1{
bool operator()(std::string& str){
return str=="aa";
}
};
struct MyFind2:public std::unary_function<_Uint32t,bool>{
bool operator()(int a) const{
return a==1;
}
};
void Func3(){
std::vector<std::string> vec1{"aa","aa","bb","aa"};
_Uint32t num1=std::count_if(vec1.begin(),vec1.end(),MyFind1());
std::cout<<num1<<std::endl;
std::vector<int> vec2{1,1,2,2,2,2,2};
_Uint32t num2=std::count_if(vec2.begin(),vec2.end(),std::not1(MyFind2()));
std::cout<<num2<<std::endl;
}
struct MyFind3{
bool operator()(A& a) {
return a.id_==1&&a.name_=="aa";
}
};
//编译类 模板 成员函数“bool std::binder2nd<MyFind4>::operator ()(A &) const”时
struct MyFind4:public std::binary_function<A,A,bool>{
bool operator()(const A& a,const A& b) const{
return a.id_==b.id_&&a.name_==b.name_;
}
};
void Func4(){
std::vector<A> vec1{A(1,"aa"),A(2,"bb")};
_Uint32t num1=std::count_if(vec1.begin(),vec1.end(),MyFind3());
std::cout<<num1<<std::endl;
_Uint32t num2=std::count_if(vec1.begin(),vec1.end(),std::bind2nd(MyFind4(),A(1,"a")));
std::cout<<num2<<std::endl;
}
int main(){
Func1();
Func2();
Func3();
Func4();
return 0;
}
输出结果:
PS D:\C++泛型编程与模板代码\build\bin\Debug> .\main.exe
3
2
3
3
5
1
0
PS D:\C++泛型编程与模板代码\build\bin\Debug>
60、STL六大组件之合并算法
代码如下:
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<functional>
class A{
public:
A(_Uint32t id,std::string name)
:id_(id)
,name_(name)
{}
A() {}
_Uint32t GetId(){
return id_;
}
std::string& GetName(){
return name_;
}
private:
_Uint32t id_;
std::string name_;
};
void Func1(){
std::vector<int> vec1{ 1,2,3,4 };
std::vector<int> vec2{ 3,4,5,6 };
std::vector<int> vec3;
vec3.resize(vec1.size()+vec2.size());
// std::merge(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), vec3.begin());
// std::for_each(vec3.begin(),vec3.end(),[=](_Uint32t num)->void{
// std::cout<<num<<" ";
// });
std::merge(vec1.begin(),vec1.end(),vec2.begin(),vec2.end(),vec3.begin(),std::less<int>());
std::for_each(vec3.begin(),vec3.end(),[=](_Uint32t num)->void{
std::cout<<num<<" ";
});
std::cout<<std::endl;
}
struct MyFind1 {
bool operator()(A& a, A& b) {
return a.GetId() < b.GetId();
}
};
void Func2(){
std::vector<A> vec1{ A(1,"tom"),A(2,"tom"),A(3,"tom"),A(4,"tom") };
std::vector<A> vec2{ A(3,"tom"),A(4,"tom"),A(5,"tom"),A(6,"tom") };
std::vector<A> vec3;
vec3.resize(vec1.size() + vec2.size());
std::merge(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), vec3.begin(),MyFind1());
for(auto start=vec3.begin();start!=vec3.end();start++){
std::cout<<(*start).GetId()<<" "<<(*start).GetName()<<std::endl;
}
}
int main(){
Func1();
Func2();
return 0;
}
输出结果:
PS D:\C++泛型编程与模板代码\build\bin\Debug> .\main.exe
1 2 3 3 4 4 5 6
1 tom
2 tom
3 tom
3 tom
4 tom
4 tom
5 tom
6 tom
PS D:\C++泛型编程与模板代码\build\bin\Debug>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g9oOK6yD-1671200465360)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20221215192445402.png)]
61、随机数(rand)和随机数种子(srand)的理解
实际开发应用时,我们代码中有可能会使用到随机数。所以今天来看看随机数是怎么生成的。
-
首先rand函数可以用来产生一个数,它具备这种功能。
- rand相关的头文件为#include<stdlib.h>
- rand()的内部实现是用线性同余法做的,它不是真的随机数,因其周期特别长,故在一定的范围里可看成是随机的。rand()返回一随机数值的范围在0至RAND_MAX 间。RAND_MAX的范围最少是在32767之间(int),用unsigned int 双字节是65535,四字节是4294967295的整数范围。0~RAND_MAX每个数字被选中的机率是相同的。用户未设定随机数种子时,系统默认的随机数种子为1。rand()产生的是伪随机数字,每次执行时是相同的,若要不同,用函数srand()初始化它。
-
srand函数用来播种随机种子,能够产生一个随机数。(播下种子seed,它啥样大家都不知道)
srand()用来设置rand()产生随机数时的随机数种子。参数seed必须是个整数,通常可以利用time(0)的返回值或NULL来当做seed。如果每次seed都设相同值,rand()所产生的随机数值每次就会一样。“相同的种子对应相同的数值”。
-
time函数是用来计算时间的秒数的。
此函数会返回从公元 1970 年1 月1 日的UTC 时间从0 时0 分0 秒算起到现在所经过的秒数。如果t 并非空指针的话,此函数也会将返回值存到t 指针所指的内存。
获取随机数的代码如下:
srand((unsigned int)time(NULL))
for(int i=0;i<10;i++){
//产生0到9之间的随机数
std::cout<<rand()%10<<" ";
}
注意:
-
这里的NULL还可以使用0。类型我们一般都是获取无符号整形,这个获取的随机数也只能是整数。
-
srand函数不可以放入循环内部,否则(1s以内)产生的一直都是一个数(每一秒都会产生一个随机数)。
当然你如果非要这么做,也可以在里面加个延迟函数sleep(1);但是我觉得大可不必搞这么复杂,所以上面的代码是最容易实现随机数的了。
62、STL六大组件之随机算法(洗牌算法)
/*
洗牌算法 打乱容器中数据顺序
void random_shuffle(begin(),end())
void shuffle(begin(),end(),func)
*/
代码如下:
#include<iostream>
//#include<stdlib.h>
#include<time.h>
#include<vector>
#include<string>
#include<algorithm>
#include<random>
/*
洗牌算法 打乱容器中数据顺序
void random_shuffle(begin(),end())
void shuffle(begin(),end(),func)
*/
class A{
public:
A(_Uint32t id,std::string name)
:id_(id)
,name_(name)
{}
_Uint32t GetId(){
return id_;
}
std::string GetName(){
return name_;
}
private:
_Uint32t id_;
std::string name_;
};
struct MyRand{
int operator()(int i){
return rand()%i;
}
};
void Func1(){
srand((unsigned int)time(NULL)); //随机数种子,无符号整数,用时间来作为随机数种子
std::vector<std::string> vec1{"aa","bb","cc","dd"};
std::random_shuffle(vec1.begin(),vec1.end(),MyRand());
std::for_each(vec1.begin(),vec1.end(),[=](std::string& str)->void{
std::cout<<str<<" ";
});
std::cout<<std::endl;
std::cout<<std::endl;
std::random_device rd;
std::shuffle(vec1.begin(),vec1.end(),std::default_random_engine(rd()));
std::for_each(vec1.begin(),vec1.end(),[=](std::string& str)->void{
std::cout<<str<<" ";
});
std::cout<<std::endl;
std::cout<<std::endl;
}
void Func2(){
std::vector<A> vec1{A(1,"aa"),A(2,"bb"),A(3,"cc")};
std::random_shuffle(vec1.begin(),vec1.end(),MyRand());
for(auto start=vec1.begin();start!=vec1.end();start++){
std::cout<<(*start).GetId()<<" "<<(*start).GetName()<<std::endl;
}
std::cout<<std::endl;
std::random_device rd;
std::shuffle(vec1.begin(),vec1.end(),std::default_random_engine(rd()));
for(auto start=vec1.begin();start!=vec1.end();start++){
std::cout<<(*start).GetId()<<" "<<(*start).GetName()<<std::endl;
}
std::cout<<std::endl;
}
int main(){
Func1();
Func2();
return 0;
}
输出结果:
PS D:\C++泛型编程与模板代码\build\bin\Debug> .\main.exe
aa dd bb cc
aa bb dd cc
1 aa
2 bb
3 cc
3 cc
1 aa
2 bb
PS D:\C++泛型编程与模板代码\build\bin\Debug>
63、STL六大组件之排序算法和反转算法
/*
void sort(begin(),end(),func)
void reverse(begin(),end())
*/
// not1 是构造一个与谓词结果相反的一元函数对象
// not2 是构造一个与谓词结果相反的二元函数对象
// 二元谓词 ,谓词,bool类型的函数对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tKJ7Puzk-1671200465361)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20221216131400415.png)]
代码如下:
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<functional>
/*
void sort(begin(),end(),func)
void reverse(begin(),end())
*/
class A{
public:
A(_Uint32t id,std::string name)
:id_(id)
,name_(name)
{}
_Uint32t GetId(){
return id_;
}
std::string& GetName(){
return name_;
}
private:
_Uint32t id_;
std::string name_;
};
struct MySort1{
void operator()(_Uint32t num){
std::cout<<num<<" ";
}
};
void Func1(){
std::vector<int> vec1{1,3,5,2,4,6};
std::sort(vec1.begin(),vec1.end());
std::for_each(vec1.begin(),vec1.end(),[&](_Uint32t num)->void{
std::cout<<num<<" ";
});
std::cout<<std::endl;
std::sort(vec1.begin(),vec1.end(),std::greater<int>());
std::for_each(vec1.begin(),vec1.end(),MySort1());
std::cout<<std::endl;
}
struct MySort2{
bool operator()(A& a,A& b){
return a.GetId()>b.GetId();
}
};
// not1 是构造一个与谓词结果相反的一元函数对象
// not2 是构造一个与谓词结果相反的二元函数对象
// 二元谓词 ,谓词,bool类型的函数对象
struct MySort3:public std::binary_function<A,A,bool>{
bool operator()(A a,A b) const{
return a.GetId()>b.GetId();
}
};
void Func2(){
std::vector<A> vec1{
A(1,"1"),
A(11,"11"),
A(111,"111"),
A(2,"2"),
A(22,"22"),
A(333,"333")
};
std::sort(vec1.begin(),vec1.end(),MySort2());
for(auto start=vec1.begin();start!=vec1.end();start++){
std::cout<<(*start).GetId()<<" "<<(*start).GetName()<<std::endl;
}
std::sort(vec1.begin(),vec1.end(),std::not2(MySort3()));
for(auto start=vec1.begin();start!=vec1.end();start++){
std::cout<<(*start).GetId()<<" "<<(*start).GetName()<<std::endl;
}
std::cout<<std::endl<<std::endl;
}
void Func3(){
std::vector<int> vec1{1,3,5,2,4,6};
std::reverse(vec1.begin(),vec1.end());
std::for_each(vec1.begin(),vec1.end(),[&](_Uint32t num)->void{
std::cout<<num<<" ";
});
std::cout<<std::endl<<std::endl;
}
void Func4(){
std::vector<A> vec1{
A(1,"1"),
A(11,"11"),
A(111,"111"),
A(2,"2"),
A(22,"22"),
A(333,"333")
};
std::sort(vec1.begin(),vec1.end(),MySort2());
for(auto start=vec1.begin();start!=vec1.end();start++){
std::cout<<(*start).GetId()<<" "<<(*start).GetName()<<std::endl;
}
std::reverse(vec1.begin(),vec1.end());
for(auto start=vec1.begin();start!=vec1.end();start++){
std::cout<<(*start).GetId()<<" "<<(*start).GetName()<<std::endl;
}
}
int main(){
Func1();
Func2();
Func3();
Func4();
return 0;
}
输出结果:
PS D:\C++泛型编程与模板代码\build\bin\Debug> .\main.exe
1 2 3 4 5 6
6 5 4 3 2 1
333 333
111 111
22 22
11 11
2 2
1 1
1 1
2 2
11 11
22 22
111 111
333 333
6 4 2 5 3 1
333 333
111 111
22 22
11 11
2 2
1 1
1 1
2 2
11 11
22 22
111 111
333 333
PS D:\C++泛型编程与模板代码\build\bin\Debug>
64、STL六大组件之拷贝算法和替换算法
/*
将begin()1和end()1中的容器的元素拷贝到另一个容器2中,
从begin()2开始填充,目标容器使用前要先开辟空间
iterator copy(begin()1,end()1,begin()2)
将begin()和end()范围内等于oldVal的元素替换成newVal
void replace(begin(),end(),oldVal,newVal)
将begin(),end()范围内符合func条件的元素,替换成newVal
void replace_if(begin(),end(),func,newVal)
将begin()1,end()1范围内的元素cp到容器2中,从begin()2处开始填充,当原容器中的元素
等于oldVal时,目标容器中的用newVal替换,目标容器使用前要先确定空间
iterator replace_copy(begin()1,end()1,begin()2,oldVal,newVal)
将begin()1,end()1范围中的元素cp到容器2中,从begin()2开始填充,当原容器中的元素
符合条件func时,用目标容器中的newVal替换,目标容器使用前要先确定空间
iterator replace_copy_if(begin()1,end()1,func,newVal)
交换元素
void swap(v1,v2)
*/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gPnGJtF4-1671200465362)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20221216150032320.png)]
代码如下:
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<functional>
/*
将begin()1和end()1中的容器的元素拷贝到另一个容器2中,
从begin()2开始填充,目标容器使用前要先开辟空间
iterator copy(begin()1,end()1,begin()2)
将begin()和end()范围内等于oldVal的元素替换成newVal
void replace(begin(),end(),oldVal,newVal)
将begin(),end()范围内符合func条件的元素,替换成newVal
void replace_if(begin(),end(),func,newVal)
将begin()1,end()1范围内的元素cp到容器2中,从begin()2处开始填充,当原容器中的元素
等于oldVal时,目标容器中的用newVal替换,目标容器使用前要先确定空间
iterator replace_copy(begin()1,end()1,begin()2,oldVal,newVal)
将begin()1,end()1范围中的元素cp到容器2中,从begin()2开始填充,当原容器中的元素
符合条件func时,用目标容器中的newVal替换,目标容器使用前要先确定空间
iterator replace_copy_if(begin()1,end()1,func,newVal)
交换元素
void swap(v1,v2)
*/
class A{
public:
A(_Uint32t id,std::string name)
:id_(id)
,name_(name)
{}
A(){}
_Uint32t GetId(){
return id_;
}
std::string& GetName(){
return name_;
}
bool operator==(const A& a){
return this->id_==a.id_&&this->name_==a.name_;
}
// private:
_Uint32t id_;
std::string name_;
};
void Func1(){
std::vector<int> vec1{1,3,5,2,4,6};
std::vector<int> vec2;
vec2.resize(vec1.size());
auto iter1=std::copy(vec1.begin(),vec1.end(),vec2.begin());
for(auto iter1=vec2.begin();iter1!=vec2.end();iter1++){
std::cout<<(*iter1)<<" ";
}
std::cout<<std::endl<<std::endl;
}
void Func2(){
std::vector<A> vec1{
A(1,"1")
,A(11,"11")
,A(111,"111")
};
std::vector<A> vec2;
vec2.resize(vec1.size());
auto iter1=std::copy(vec1.begin(),vec1.end(),vec2.begin());
for(auto iter1=vec2.begin();iter1!=vec2.end();iter1++){
std::cout<<(*iter1).GetId()<<" "<<(*iter1).GetName()<<std::endl;
}
std::cout<<std::endl;
}
void Func3(){
std::vector<int> vec1{1,3,5,2,4,6};
std::for_each(vec1.begin(),vec1.end(),[=](_Uint32t num)->void{
std::cout<<num<<" ";
});
std::cout<<std::endl;
std::replace(vec1.begin(),vec1.end(),1,100);
std::for_each(vec1.begin(),vec1.end(),[&](_Uint32t id)->void{
std::cout<<id<<" ";
});
std::cout<<std::endl<<std::endl;
}
void Func4(){
std::vector<A> vec1{
A(1,"1")
,A(11,"11")
,A(111,"111")
};
std::replace(vec1.begin(),vec1.end(),A(11,"11"),A(1111,"1111"));
for(auto start=vec1.begin();start!=vec1.end();start++){
std::cout<<(*start).id_<<" "<<(*start).name_<<std::endl;
}
}
struct MyReplace1{
bool operator()(const int a){
return a==1;
}
};
struct MyReplace2:public std::binary_function<int,int,bool>{
bool operator()(_Uint32t a,_Uint32t b) const{
return a==b;
}
};
void Func5(){
std::vector<int> vec1{1,3,5,2,4,6};
std::replace_if(vec1.begin(),vec1.end(),MyReplace1(),100);
std::for_each(vec1.begin(),vec1.end(),[=](_Uint32t id)->void{
std::cout<<id<<" ";
});
std::cout<<std::endl;
std::replace_if(vec1.begin(),vec1.end(),std::bind2nd(MyReplace2(),5),50);
std::for_each(vec1.begin(),vec1.end(),[=](_Uint32t id)->void{
std::cout<<id<<" ";
});
std::cout<<std::endl;
std::cout<<std::endl<<std::endl;
}
void Func6(){
std::vector<int> vec1{1,3,5};
std::vector<int> vec2{2,4,6};
auto start1=vec1.begin();
auto end1=vec1.end();
auto start2=vec2.begin();
auto end2=vec2.end();
printf("%p %d\n",start1,*start1);
printf("%p %d\n",start2,*start2);
// printf("%p %d\n",end1,*end1);
// printf("%p %d\n",end2,*end2);
std::swap(vec1,vec2);
auto start3=vec1.begin();
auto start4=vec2.begin();
auto end3=vec1.end();
auto end4=vec2.end();
printf("%p %d\n",start3,*start3);
printf("%p %d\n",start4,*start4);
// printf("%p %d\n",end3,*end3);
// printf("%p %d\n",end4,*end4);
}
int main(){
Func1();
Func2();
Func3();
Func4();
Func5();
Func6();
return 0;
}
输出结果:
PS D:\C++泛型编程与模板代码\build\bin\Debug> .\main.exe
1 3 5 2 4 6
1 1
11 11
111 111
1 3 5 2 4 6
100 3 5 2 4 6
1 1
1111 1111
111 111
100 3 5 2 4 6
100 3 50 2 4 6
000000CFE5B7F6A0 1
000000CFE5B7F6C0 2
000000CFE5B7F6E0 2
000000CFE5B7F700 1
PS D:\C++泛型编程与模板代码\build\bin\Debug>
65、STL六大组件之算术生成算法和填充算法
/*
算术生成算法
#include<numberic>
T accumulate(begin(),end(),val,func)
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 modules<T> 取模
template<class T>T negate<T> 取反
填充算法,容器使用前要先分配空间
void fill(begin(),end(),val)
*/
代码如下:
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<numeric>
/*
算术生成算法
#include<numberic>
T accumulate(begin(),end(),val,func)
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 modules<T> 取模
template<class T>T negate<T> 取反
填充算法,容器使用前要先分配空间
void fill(begin(),end(),val)
*/
class A{
public:
A(_Uint32t id,std::string name)
:id_(id)
,name_(name)
{}
A(){}
_Uint32t GetId(){
return id_;
}
std::string& GetName(){
return name_;
}
private:
_Uint32t id_;
std::string name_;
};
void Func1(){
std::vector<int> vec1{1,3,5,2,4,6};
//std::accumulate()默认是加法
auto iter1=std::accumulate(vec1.begin(),vec1.end(),0); //0+1+3+5+2+4+6
std::cout<<iter1<<std::endl;
auto iter2=std::accumulate(vec1.begin(),vec1.end(),10); //10+1+3+5+2+4+6
std::cout<<iter2<<std::endl;
auto iter3=std::accumulate(vec1.begin(),vec1.end(),0,std::minus<int>()); //0-1-3-5-2-4-6
std::cout<<iter3<<std::endl;
}
struct MyPlus{
_Uint32t operator()(_Uint32t num,A a){
return num+a.GetId();
}
};
void Func2(){
std::vector<A> vec1{
A(1,"1")
,A(11,"11")
,A(111,"111")
};
auto iter1=std::accumulate(vec1.begin(),vec1.end(),0,MyPlus());
std::cout<<iter1<<std::endl;
}
void Func3(){
std::vector<int> vec1;
vec1.resize(10);
std::for_each(vec1.begin(),vec1.end(),[=](_Uint32t num)->void{
std::cout<<num<<" ";
});
std::cout<<std::endl;
std::fill(vec1.begin(),vec1.end(),100);
std::for_each(vec1.begin(),vec1.end(),[=](_Uint32t num)->void{
std::cout<<num<<" ";
});
std::cout<<std::endl;
}
void Func4(){
std::vector<A> vec1;
vec1.resize(3);
for(auto start=vec1.begin();start!=vec1.end();start++){
std::cout<<(*start).GetId()<<" "<<(*start).GetName()<<std::endl;
}
std::cout<<std::endl;
std::fill(vec1.begin(),vec1.end(),A(1,"1"));
for(auto start=vec1.begin();start!=vec1.end();start++){
std::cout<<(*start).GetId()<<" "<<(*start).GetName()<<std::endl;
}
std::cout<<std::endl;
}
int main(){
Func1();
Func2();
Func3();
Func4();
return 0;
}
输出结果:
PS D:\C++泛型编程与模板代码\build\bin\Debug> .\main.exe
21
31
-21
123
0 0 0 0 0 0 0 0 0 0
100 100 100 100 100 100 100 100 100 100
3452816845
3452816845
3452816845
1 1
1 1
1 1
PS D:\C++泛型编程与模板代码\build\bin\Debug>
66、STL六大组件之集合算法
/*
*
* #include<algorithm>
*
* begin1 源容器1 开始迭代器
* end1 源容器1 结束迭代器
* begin2 源容器2 开始迭代器
* end2 源容器2 结束迭代器
* begin3 目标容器开如迭代器
* func 比较规则 默认 less
*
*
*
* 交集 源容器元素都必须是有序的,且排序规则要保持一致,目标容器使用前要分配空间
* iterator set_intersection(begin1,end1,begin2,end2,begin3,func);
*
*
* 并集 源容器元素都必须是有序的,且排序规则要保持一致,目标容器使用前要分配空间
* iterator set_union(begin1,end1,begin2,end2,begin3,func);
*
*
* 差集 源容器元素都必须是有序的,且排序规则要保持一致,目标容器使用前要分配空间
* iterator set_difference(begin1,end1,begin2,end2,begin3,func);
*
*
* */
代码如下:
#include <iostream>
#include<vector>
#include<functional>
#include<algorithm>
#include<numeric>
#include<string>
using namespace std;
/*
*
* #include<algorithm>
*
* begin1 源容器1 开始迭代器
* end1 源容器1 结束迭代器
* begin2 源容器2 开始迭代器
* end2 源容器2 结束迭代器
* begin3 目标容器开如迭代器
* func 比较规则 默认 less
*
*
*
* 交集 源容器元素都必须是有序的,且排序规则要保持一致,目标容器使用前要分配空间
* iterator set_intersection(begin1,end1,begin2,end2,begin3,func);
*
*
* 并集 源容器元素都必须是有序的,且排序规则要保持一致,目标容器使用前要分配空间
* iterator set_union(begin1,end1,begin2,end2,begin3,func);
*
*
* 差集 源容器元素都必须是有序的,且排序规则要保持一致,目标容器使用前要分配空间
* iterator set_difference(begin1,end1,begin2,end2,begin3,func);
*
*
* */
class C1{
public:
C1(int id,string name){
this->id=id;
this->name=name;
}
C1(){}
int id;
string name;
};
typedef struct myComp1:public binary_function<C1,C1,bool>{
bool operator()(const C1 &a,const C1 &b) const{
return a.id<b.id;
}
};
typedef struct myComp2{
bool operator()(const C1 &a,const C1 &b){
return a.id>b.id;
}
};
void func2(){
vector<C1>v1{C1(1,"1"),C1(22,"22"),C1(33,"33"),C1(444,"444"),C1(555,"555"),C1(999,"999")};
vector<C1>v2{C1(4,"4"),C1(33,"33"),C1(44,"44"),C1(555,"555"),C1(8888,"888")};
vector<C1>v3;
v3.resize(min(v1.size(),v2.size()));
sort(v1.begin(),v1.end(), not2(myComp1()));
sort(v2.begin(),v2.end(), not2(myComp1()));
for(auto start = v1.begin();start != v1.end();start++){
cout<<(*start).id<<" "<<(*start).name<<" ";
}
cout<<endl;
for(auto start = v2.begin();start != v2.end();start++){
cout<<(*start).id<<" "<<(*start).name<<" ";
}
cout<<endl<<endl;
set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin(),myComp2());
for(auto start = v3.begin();start != v3.end();start++){
cout<<(*start).id<<" "<<(*start).name<<" ";
}
}
void func1(){
vector<int>v1{1,4,2,5,3};
vector<int>v2{9,4,7,8,6,5};
vector<int>v3;
v3.resize(min(v1.size(),v2.size()));
sort(v1.begin(),v1.end());
sort(v2.begin(),v2.end());
set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
for(auto start = v3.begin();start != v3.end();start++){
cout<<*start<<" ";
}
}
int main(){
func2();
return 0;
}