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可以理解成一个函数对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OYo0Xun0-1671200465353)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20221215121533039.png)]

代码如下:

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>()) 默认函数对象升序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B8oCwnNE-1671200465356)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20221215121824858.png)]

#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六大组件之统计算法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jVOl7HOg-1671200465358)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20221215150121216.png)]

/*
    统计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六大组件之合并算法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GLaEikfa-1671200465359)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20221215191944810.png)]

代码如下:

#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;
}

猜你喜欢

转载自blog.csdn.net/qq_44918090/article/details/128348735