STL六大组件之算法
Posted 森明帮大于黑虎帮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL六大组件之算法相关的知识,希望对你有一定的参考价值。
文章目录
- 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> vec11,2,3,4;
std::vector<int> vec210,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> vec11,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> vec1A(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> vec11,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> vec1A(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> vec1A(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> vec1A(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> vec1A(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> vec11,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> vec21,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> vec1A(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> vec1A(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> vec21,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> vec1A(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> vec1A(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> vec11,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> vec11,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> vec11,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> vec11,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> vec11,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> vec11,3,5;
std::vector<int> vec22,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> vec11,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>v1C1(1,"1"),C1(22,"22"),C1(33,"33"),C1(444,"444"),C1(555,"555"),C1(999,"999");
vector<C1>v2C1(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>v11,4,2,5,3;
vector<int>v29,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;
以上是关于STL六大组件之算法的主要内容,如果未能解决你的问题,请参考以下文章