STL-函数对象 + 谓词 + 常用算法

本文为B站黑马程序员 C++视频学习笔记,若侵权,则删,B站搜索黑马程序员可查看原视频。

函数对象

概念:
1、重载函数调用操作符的类,其对象常称为函数对象
2、函数对象使用重载的()时,行为类似函数调用,也叫仿函数
本质:
函数对象(仿函数)是一个,不是一个函数

函数对象使用

特点:
1、函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
2、函数对象超出普通函数的概念,函数对象可以有自己的状态
3、函数对象可以作为参数传递
示例:

#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
class MyAdd
{
public:
    int operator()(int v1,int v2)
    {
        return v1+v2;
    }
};
//函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
void test01()
{
    MyAdd myAdd;
    cout<<myAdd(10,10)<<endl;
}
//函数对象超出普通函数的概念,函数对象可以有自己的状态
class MyPrint
{
public:
    MyPrint()
    {
        this->count = 0;
    }
public:
    void operator()(string test)
    {
        cout << test <<endl;
        this->count++;
    }
    int count; //内部自己状态
};
void test02()
{
    MyPrint myPrint;
    myPrint("hello world");
    myPrint("hello world");
    myPrint("hello world");
    myPrint("hello world");
    myPrint("hello world");
    cout<<"MyPrint函数调用次数为:"<<myPrint.count<<endl;
}
//函数对象可以作为参数传递
void doPrint(MyPrint &mp,string test)
{
    mp(test);
}
void test03()
{
    MyPrint myPrint;
    doPrint(myPrint,"hello C++");
}
int main()
{
    test01();
    test02();
    test03();
    return 0;
}

谓词

概念:
1、返回bool类型的仿函数称为谓词
2、如果operator()接受一个参数,那么叫做一元谓词,接受两个参数,叫做二元谓词

一元谓词

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//仿函数返回值类型是bool数据类型,称为谓词
//一元谓词

class GreaterFive
{
 public:
    bool operator()(int val)
    {
        return val > 5;
    }
};
void test01()
{
    vector<int>v;
    for(int i = 0; i < 10; i++)
    {
        v.push_back(i);
    }
    //查找容器中  有没有大于5的数字
    //GreaterFive()  -- 匿名函数对象
    vector<int>::iterator it = find_if(v.begin(),v.end(),GreaterFive());
    if(it == v.end())
    {
        cout <<"未找到"<<endl;
    }
    else
    {
        cout<<"找到了大于5的数字为:"<<*it<<endl; //output : 6
    }
}

int main()
{
    test01();
    return 0;
}

二元谓词

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//仿函数返回值类型是bool数据类型,称为谓词
//二元谓词

class MyCompare
{
 public:
    bool operator()(int val1,int val2)
    {
        return val1 > val2;
    }
};
void test01()
{
    vector<int>v;
    v.push_back(10);
    v.push_back(40);
    v.push_back(20);
    v.push_back(30);
    v.push_back(50);

    sort(v.begin(),v.end());
    for(vector<int>::iterator it = v.begin();it != v.end(); it ++)
    {
        cout << *it << "  ";
    }
    cout << endl;
    //使用函数对象,改变算法策略,变为排序规则从大到小
    sort(v.begin(),v.end(),MyCompare());
    
    cout << "---------------"<<endl;
    for(vector<int>::iterator it = v.begin();it != v.end(); it ++)
    {
        cout << *it << "  ";
    }
    cout << endl;
}

int main()
{
    test01();
    return 0;
}

内建函数对象

分类:
1、算术仿函数
2、关系仿函数
3、逻辑仿函数
用法:
1、这些仿函数所产生的对象,用法和一般函数完全相同
2、使用内建函数对象,需要引入头文件#include< functional >

算数仿函数

功能:
1、实现四则运算
2、其中negate是一元运算,其他都是二元运算
仿函数原型:

template<class T> T plus<T>     //加法仿函数
template<class T> T minus<T>     //减法仿函数
template<class T> T multiplies<T>     //乘法仿函数
template<class T> T divides<T>     //除法仿函数
template<class T> T modulus<T>     //取模仿函数
template<class T> T negate<T>     //取反仿函数

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <functional>    //包含头文件
using namespace std;
//算数仿函数

//template<class T> T negate<T>     //一元取反仿函数
void test01()
{
    negate<int>n;
    cout << n(50)<<endl;
}
//template<class T> T plus<T>     //二元加法仿函数
void test02()
{
    plus<int>p;
    cout<<p(10,20)<<endl;
}

int main()
{
    test01();
    test02();
    return 0;
}

关系仿函数

功能:
实现关系对比
仿函数原型:

template<class T> bool equal_to<T>       //等于
template<class T> bool not_equal_to<T>   //不等于
template<class T> bool greater<T>        //大于
template<class T> bool greater_equal<T>  //大于等于
template<class T> bool less<T>           //小于
template<class T> bool less_equal<T>     //小于等于

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
//内建函数对象 _关系仿函数
//大于 greater
class MyCompare
{
 public:
    bool operator()(int val1,int val2)
    {
        return val1 > val2;
    }
};

void test01()
{
    vector<int>v;
    
    v.push_back(10);
    v.push_back(30);
    v.push_back(40);
    v.push_back(20);
    v.push_back(50);
    
    for(vector<int>::iterator it = v.begin();it != v.end(); it ++)
    {
        cout << *it << "  ";
    }
    cout << endl;
    //降序
    //greater<int>()  内建函数对象
    sort(v.begin(),v.end(),greater<int>());
    
    cout << "---------------"<<endl;
    for(vector<int>::iterator it = v.begin();it != v.end(); it ++)
    {
        cout << *it << "  ";
    }
    cout << endl;
} 

int main()
{
    test01();
    return 0;
}

逻辑仿函数

函数原型:

template<class T> bool logical_and<T>       //逻辑与
template<class T> bool logical_or<T>       //逻辑或
template<class T> bool logical_not<T>       //逻辑非

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
//内建函数对象 _逻辑仿函数
//逻辑非  logical_not

void test01()
{
    vector<bool>v;
    v.push_back(true);
    v.push_back(false);
    v.push_back(true);
    v.push_back(false);
    
    for(vector<bool>::iterator it = v.begin();it != v.end(); it ++)
    {
        cout << *it << "  ";
    }
    cout << endl;
    
    //利用逻辑非  将容器v搬运到容器v2中  并执行取反操作
    vector<bool>v2;
    v2.resize(v.size());//扩容
    //搬运 logical_not<bool>()取反  函数匿名对象
    transform(v.begin(),v.end(),v2.begin(),logical_not<bool>());
    cout << "---------------"<<endl;
    for(vector<bool>::iterator it = v2.begin();it != v2.end(); it ++)
    {
        cout << *it << "  ";
    }
    cout << endl;
} 

int main()
{
    test01();
    return 0;
}

STL - 常用算法

概述:
1、算法主要是由头文件< algorithm > < functional > < numeric >组成
2、< algorithm >是所有STL头文件中最大的一个,范围涉及到比较、交换、查找、遍历操作、复制、修改等等
3、< numeric >体积很小,只包括几个在序列上面进行简单数学运算的模板函数
4、< functional > 定义了一些模板类,用以声明函数对象

常用遍历算法

原型:

for_each   //遍历容器
transform  //搬运容器到另一个容器中

for_each — 最常用的遍历算法

函数原型:

for_each(iterator beg, iterator end. _func);
//遍历算法   遍历容器元素
//beg 开始迭代器
//end 结束迭代器
//_func 函数或者函数对象

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//常用遍历算法  for_each

//普通函数
void print01(int val)
{
    cout << val << "  ";
}

//仿函数
class print02
{
public:
    void operator()(int val)
    {
        cout << val <<"  ";
    }
};

void test01()
{
    vector<int>v;
    for (int i = 0; i < 10; i ++)
    {
        v.push_back(i);
    }
    
    for_each(v.begin(),v.end(),print01);  //普通函数直接放入函数
    cout << endl;
    for_each(v.begin(),v.end(),print02());  //仿函数需要放入函数对象
    cout << endl;
} 

int main()
{
    test01();
    return 0;
}

transform — 搬运容器到另一个容器中

函数原型:

transform(iterator beg1, iterator end1, iterator beg2, _func);
//beg1 源容器开始迭代器
//end1 源容器结束迭代器
//beg2 目标容器开始迭代器
//_func 函数或者函数对象

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//常用遍历算法  搬运 transform
class Transform
{
public:
    int operator()(int v)
    {
        return v + 20;  //可以自己设置
    }
};

class MyPrint
{
public:
    void operator()(int val)
    {
        cout << val << "  ";
    }
};
void test01()
{
    vector<int>v;
    for (int i = 0; i < 10; i ++)
    {
        v.push_back(i);
    }
    
    vector<int> vTarget; //目标容器
    vTarget.resize(v.size());
    transform(v.begin(),v.end(),vTarget.begin(),Transform());  //搬运可以设置规则
    
    for_each(vTarget.begin(),vTarget.end(),MyPrint());
} 

int main()
{
    test01();
    return 0;
}

常用查找算法

原型:

find   //查找元素
find_if  //按条件查找元素
adjacent_find  //查找相邻重复元素
binary_search  //二分查找法
count   //统计元素个数
count_if   //按条件统计元素个数

find

描述:
查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器end()
注意: 自定义数据类型需要重载==号,符合find底层逻辑
函数原型:

find(iterator beg, iterator end, value); 
//按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
//beg 开始迭代器
//end 结束迭代器
//value 查找的元素

示例;

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
//查找算法
//find

//查找内置数据类型
void test01()
{
    vector<int>v;
    for (int i = 0; i < 10; i ++)
    {
        v.push_back(i);
    }
    
    //查找容器中是否有5这个元素
    vector<int>::iterator it = find(v.begin(),v.end(),5);
    if(it == v.end())
    {
        cout<<"未查到!"<<endl;
    }
    else
    {
        cout<<"找到:"<<*it<<endl;
    }
} 

//查找自定义数据类型
class Person
{
public:
    string m_Name;
    int m_Age;
    Person(string name, int age)
    {
        this -> m_Name = name;
        this -> m_Age = age;
    }
    //重载 == 底层find知道如何对比Person数据类型
    bool operator == (const Person &p)
    {
        if(this->m_Name == p.m_Name && this->m_Age == p.m_Age)
        {
            return true;
        }
        else
        {return false;}
    }
};

void test02()
{
    vector<Person>v;
    Person p1("aaa",10);
    Person p2("bbb",20);
    Person p3("ccc",30);
    Person p4("ddd",40);
    
    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p3);
    v.push_back(p4);
    
    Person pp("bbb",20);
    vector<Person>::iterator it = find(v.begin(),v.end(),pp);
    
    if(it == v.end())
    {
        cout<<"未查到!"<<endl;
    }
    else
    {
        cout<<"找到: 名字:"<<(*it).m_Name<<"  年龄:"<<it->m_Age<<endl;
    }
}
int main()
{
    test01();
    test02();
    return 0;
}

find_if

函数原型:

find_if(iterator beg, iterator end, _Pred);
//按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
//beg 开始迭代器
//end 结束迭代器
//_Pred 函数或者谓词(返回bool类型的仿函数)

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
//查找算法
//find_if

//查找内置数据类型
class GreaterFive
{
public:
    bool operator()(int val)
    {
        return val > 5;
    }
};
void test01()
{
    vector<int>v;
    for (int i = 0; i < 10; i ++)
    {
        v.push_back(i);
    }
    
    //查找容器中是否有5这个元素
    vector<int>::iterator it = find_if(v.begin(),v.end(),GreaterFive());
    if(it == v.end())
    {
        cout<<"未查到!"<<endl;
    }
    else
    {
        cout<<"找到大于5的数字为:"<<*it<<endl;
    }
} 

//查找自定义数据类型
class Person
{
public:
    string m_Name;
    int m_Age;
    Person(string name, int age)
    {
        this -> m_Name = name;
        this -> m_Age = age;
    }
};

class Greater20
{
public:
    bool operator()(Person &p)
    {
        return p.m_Age > 20;
    }
};
void test02()
{
    vector<Person>v;
    Person p1("aaa",10);
    Person p2("bbb",20);
    Person p3("ccc",30);
    Person p4("ddd",40);
    
    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p3);
    v.push_back(p4);
    
    //找年龄大于20的人
    vector<Person>::iterator it = find_if(v.begin(),v.end(),Greater20());
    
    if(it == v.end())
    {
        cout<<"未查到!"<<endl;
    }
    else
    {
        cout<<"找到: 名字:"<<(*it).m_Name<<"  年龄:"<<it->m_Age<<endl;
    }
}
int main()
{
    test01();
    test02();
    return 0;
}

adjacent_find — 查找相邻重复元素

原型:

adjacent_find(iterator beg,iterator end);
//查找相邻重复元素,返回相邻元素第一个位置的迭代器
//beg 开始迭代器
//end 结束迭代器

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//查找算法
//adjacent_find

void test01()
{
    vector<int>v;
    v.push_back(0);
    v.push_back(2);
    v.push_back(0);
    v.push_back(3);
    v.push_back(1);
    v.push_back(4);
    v.push_back(3);
    v.push_back(3);

    vector<int>::iterator it = adjacent_find(v.begin(),v.end());
    
    if(it == v.end())
    {
        cout<<"未找到相邻重复元素!"<<endl;
    }
    else
    {
        cout<<"找到相邻重复元素:"<<*it<<endl;
    }
} 
int main()
{
    test01();
    return 0;
}

binary_search — 查找指定元素是否存在

函数原型:

bool binary_search(iterator beg, iterator end, value);
//查找指定的元素,查到 返回true  否则返回false
//注意:在无序序列中不可用
//beg 开始迭代器
//end 结束迭代器
//value 查找的元素

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//查找算法
//binary_search

void test01()
{
    vector<int>v;
    
    for (int i = 0; i < 10; i ++)
    {
        v.push_back(i);
    }

    //查找容器中是否有9 元素
    //注意:容器必须是有序的序列
    //如果是无序序列,结果未知!
    bool ret = binary_search(v.begin(),v.end(),9);
    
    if(ret)
    {
        cout<<"找到元素!"<<endl;
    }
    else
    {
        cout<<"未找到元素!:"<<endl;
    }
} 


int main()
{
    test01();
    return 0;
}

count — 统计元素个数

函数原型:

count(iterator beg, iterator end,value);
//统计元素出现次数
//beg 开始迭代器
//end 结束迭代器
//value 统计的元素

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
//查找算法
//count

//统计内置数据类型
void test01()
{
    vector<int>v;
    
    v.push_back(10);
    v.push_back(40);
    v.push_back(30);
    v.push_back(40);
    v.push_back(20);
    v.push_back(40);
    
    int num = count(v.begin(),v.end(),40);
    
    cout<<"40的元素个数为:"<<num<<endl;
} 

//统计自定义数据类型
class Person
{
public:
    string m_Name;
    int m_Age;
    Person(string name, int age)
    {
        this -> m_Name = name;
        this -> m_Age = age;
    }
    bool operator== (const Person &p)  //底层要求必须要加上const
    {
        if(this->m_Age == p.m_Age)
        {return true;}
        else
        {return false;}
    }
};
void test02()
{
    vector<Person>v;
    Person p1("刘备",35);
    Person p2("关羽",35);
    Person p3("张飞",35);
    Person p4("赵云",30);
    Person p5("曹操",40);
    
    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p3);
    v.push_back(p4);
    v.push_back(p5);
    
    Person p("诸葛亮",35);
    int num = count(v.begin(),v.end(),p);
    cout<<"和诸葛亮同岁数的人员个数为:"<<num<<endl;
    
}
int main()
{
    test01();
    test02();
    return 0;
}

count_if — 按条件统计元素个数

函数原型:

count_if(iterator beg,iterator end, _Pred);
//按条件统计元素出现次数
//beg 开始迭代器
//end 结束迭代器
//_Pred 谓词

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
//查找算法
//count_if

//统计内置数据类型
class Greater20
{
public:
    bool operator()(int val)
    {
        return val > 20;
    }
};
void test01()
{
    vector<int>v;
    
    v.push_back(10);
    v.push_back(40);
    v.push_back(30);
    v.push_back(20);
    v.push_back(40);
    v.push_back(20);
    
    int num = count_if(v.begin(),v.end(),Greater20());
    
    cout<<"大于20的元素个数为:"<<num<<endl;
} 

//统计自定义数据类型
class Person
{
public:
    string m_Name;
    int m_Age;
    Person(string name, int age)
    {
        this -> m_Name = name;
        this -> m_Age = age;
    }
};
class AgeGreater20
{
public:
    bool operator()(const Person &p)
    {
        return p.m_Age > 20;
    }
};
void test02()
{
    vector<Person>v;
    Person p1("刘备",35);
    Person p2("关羽",35);
    Person p3("张飞",35);
    Person p4("赵云",40);
    Person p5("曹操",20);
    
    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p3);
    v.push_back(p4);
    v.push_back(p5);
    
    //统计  大于20岁人员个数
    int num = count_if(v.begin(),v.end(),AgeGreater20());
    cout<<"大于20岁人员个数:"<<num<<endl;
    
}
int main()
{
    test01();
    test02();
    return 0;
}

常用排序算法

算法简介:

sort     //对容器内元素进行排序
random_shuffle  //洗牌 指定范围内的元素随机调整次序
merge  //容器元素合并  并存储到另一个容器中
reverse  //反转指定范围的元素

sort — 对容器内元素进行排序

函数原型:

sort(iterator beg,iterator end, _Pred);
//beg 开始迭代器
//end 结束迭代器
//_Pred 谓词

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;
//排序算法
//sort

void MyPrint(int val)
{
    cout << val <<"  ";
}
void test01()
{
    vector<int>v;
    
    v.push_back(10);
    v.push_back(40);
    v.push_back(30);
    v.push_back(20);
    v.push_back(40);
    
    sort(v.begin(),v.end());
    for_each(v.begin(),v.end(),MyPrint);
    cout << endl;
    
    sort(v.begin(),v.end(),greater<int>()); //内置谓词
    for_each(v.begin(),v.end(),MyPrint);
    cout << endl;
} 


int main()
{
    test01();
    return 0;
}

random_shuffle — 洗牌

random_shuffle : 指定范围内的元素随机调整次序
函数原型:

random_shuffle(iterator beg, iterator end);
//指定范围内的元素随机调整次序
//beg 开始迭代器
//end 结束迭代器

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;
//排序算法
//random_shuffle

void myPrint(int val)
{
    cout<<val<<"  ";
}
void test01()
{
    srand((unsigned int)time(NULL));
    vector<int>v;
    
    for(int i = 0;i<10;i++)
    {
        v.push_back(i);
    }
    
    //利用洗牌 算法 打乱顺序
    random_shuffle(v.begin(),v.end());
    for_each(v.begin(),v.end(),myPrint); 
    cout << endl;
} 

int main()
{
    test01();
    return 0;
}

总结: random_shuffle洗牌算法比较实用,使用时记得加随机数种子

merge — 合并两容器元素 存储到另一个容器

函数原型:

merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//容器元素合并 并存储到另一个容器中
//注意:两个容器必须是有序的
//beg1 容器1开始迭代器
//end1 容器1结束迭代器
//beg2 容器2开始迭代器
//end2 容器2结束迭代器
//dest 目标容器开始迭代器

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//排序算法
//merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

void myPrint(int val)
{
    cout<<val<<"  ";
}
void test01()
{
    vector<int>v1;
    vector<int>v2;
    for(int i = 0;i<10;i++)
    {
        v1.push_back(i);
        v2.push_back(i + 1);
    }
    vector<int>vTarget;
    vTarget.resize(v1.size() + v2.size());
    merge(v1.begin(),v1.end(),v2.begin(),v2.end(),vTarget.begin());
    for_each(vTarget.begin(),vTarget.end(),myPrint);   
    //output :0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10
    cout << endl;
} 

int main()
{
    test01();
    return 0;
}

总结: merge合并的两个容器必须是有序序列

reverse — 将容器内元素进行反转

函数原型:

reverse(iterator beg, iterator end);
//反转指定范围的元素
//beg 开始迭代器
//end 结束迭代器

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//排序算法
//reverse(iterator beg, iterator end);

void myPrint(int val)
{
    cout<<val<<"  ";
}
void test01()
{
    vector<int>v;
    v.push_back(10);
    v.push_back(30);
    v.push_back(50);
    v.push_back(20);
    v.push_back(40);
     
    cout << "反转前:"<<endl;
    for_each(v.begin(),v.end(),myPrint);   //output: 10 30 50 20 40
    cout << endl;
    
    cout << "反转后:"<<endl;
    reverse(v.begin(),v.end());
    for_each(v.begin(),v.end(),myPrint);   //output: 40 20 50 30 10
} 

int main()
{
    test01();
    return 0;
}

常用拷贝和替换算法

算法简介:

copy   //容器内指定范围的元素拷贝到另一容器中
replace  //将容器内指定范围的旧元素替换为新元素
replace_if  //容器内指定范围满足条件的元素替换为新元素
swap   //互换两个容器的元素

copy — 拷贝数据到另一容器

函数原型:

copy(iterator beg, iterator end, iterator dest);
//beg 开始迭代器
//end 结束迭代器
//dest 目标起始迭代器

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//常用拷贝和替换算法
//copy(iterator beg, iterator end, iterator dest);

void myPrint(int val)
{
    cout<<val<<"  ";
}
void test01()
{
    vector<int>v;
    v.push_back(10);
    v.push_back(30);
    v.push_back(50);
    v.push_back(20);
    v.push_back(40);
     
    vector<int>v2;
    v2.resize(v.size());
    copy(v.begin(),v.end(),v2.begin());
    
    for_each(v2.begin(),v2.end(),myPrint);
} 

int main()
{
    test01();
    return 0;
}

replace — 指定范围旧元素替换为新元素

函数原型:

replace(iterator beg, iterator end, oldvalue, newvalue);
//将区间内旧元素 替换为 新元素
//beg 开始迭代器
//end 结束迭代器
//oldvalue 旧元素
//newvalue 新元素

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//常用拷贝和替换算法
//replace(iterator beg, iterator end, oldvalue, newvalue);

class MyPrint
{
public:
    void operator()(int val)
    {
        cout << val <<"  ";
    }
};
void test01()
{
    vector<int>v;
    v.push_back(20);
    v.push_back(30);
    v.push_back(50);
    v.push_back(30);
    v.push_back(40);
    v.push_back(20);
    v.push_back(10);
    v.push_back(20);
    
    cout <<"替换前:"<<endl; 
    for_each(v.begin(),v.end(),MyPrint());  //output : 20 30 50 30 40 20 10 20
    cout << endl;
    
    cout <<"替换后:"<<endl;
    //将20 替换成 2000
    replace(v.begin(),v.end(),20,2000);
    for_each(v.begin(),v.end(),MyPrint());  //output : 2000 30 50 30 40 2000 10 2000
    cout << endl;
    
} 

int main()
{
    test01();
    return 0;
}

replace_if

函数原型: 利用仿函数灵活筛选条件

replace_if(iterator beg, iterator end, _pred, newvalue);
//按条件替换元素  满足条件的替换成指定元素
//beg 开始迭代器
//end 结束迭代器
//_pred 谓词
//newvalue替换的新元素

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//常用拷贝和替换算法
//replace_if(iterator beg, iterator end, _pred, newvalue);

class MyPrint
{
public:
    void operator()(int val)
    {
        cout << val <<"  ";
    }
};
class Greater30
{
public:
    bool operator()(int val)
    {
        return val >= 30;
    }
};
void test01()
{
    vector<int>v;
    v.push_back(10);
    v.push_back(40);
    v.push_back(20);
    v.push_back(40);
    v.push_back(30);
    v.push_back(50);
    v.push_back(20);
    v.push_back(30);
    
    cout <<"替换前:"<<endl; 
    for_each(v.begin(),v.end(),MyPrint());  //output : 10  40  20  40  30  50  20  30
    cout << endl;
    
    cout <<"替换后:"<<endl;
    //将大于等于30  替换成3000
    replace_if(v.begin(),v.end(),Greater30(),3000);
    for_each(v.begin(),v.end(),MyPrint());  //output : 10  3000  20  3000  3000  3000  20  3000 
    cout << endl;
    
} 

int main()
{
    test01();
    return 0;
}

swap — 互换两个容器的元素

函数原型:

swap(container c1, container c2);
//互换两个容器中的元素
//c1 容器1
//c2 容器2

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//常用拷贝和替换算法
//swap(container c1, container c2);

class MyPrint
{
public:
    void operator()(int val)
    {
        cout << val <<"  ";
    }
};

void test01()
{
    vector<int>v1;
    vector<int>v2;
    
    for(int i = 0; i < 10; i ++)
    {
        v1.push_back(i);
        v2.push_back(i+100);
    }
    
    cout <<"交换前:"<<endl;
    for_each(v1.begin(),v1.end(),MyPrint());  
    cout << endl;
    for_each(v2.begin(),v2.end(),MyPrint());  
    cout << endl;

    cout <<"交换后:"<<endl;
    swap(v1,v2);
    for_each(v1.begin(),v1.end(),MyPrint());  
    cout << endl;
    for_each(v2.begin(),v2.end(),MyPrint());  
    cout << endl;
    
} 

int main()
{
    test01();
    return 0;
}

常用算术生成算法

注意:
算术生成算法属于小型算法,使用时包含的头文件为 #include< numeric >
算法简介:

accumulate   //计算容器元素累计总和
fill       //向容器中添加元素

accumulate — 计算区间内容器元素累计总和

函数原型:

accumulate(iterator beg, iterator end, value);
//计算容器元素累计总和
//beg 开始迭代器
//end 结束迭代器
//value 起始值

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
//常用算术生成算法
//accumulate(iterator beg, iterator end, value);

void test01()
{
    vector<int>v;
    
    for(int i = 0; i <= 100; i ++)
    {
        v.push_back(i);
    }
    
    int total = accumulate(v.begin(),v.end(),0);  //0 - 起始累加值
    cout<<"total = "<< total<<endl;  // output : 5050
} 

int main()
{
    test01();
    return 0;
}

fill — 填充指定元素

函数原型:

fill(iterator beg, iterator end, value);
//向容器中填充元素
//beg 开始迭代器
//end 结束迭代器
//value 填充的值

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;
//常用算术生成算法
//fill(iterator beg, iterator end, value);

class MyPrint
{
public:
    void operator()(int val)
    {
        cout << val <<"  ";
    }
};

void test01()
{
    vector<int>v;
    
    v.resize(10);
    
    //后期重新填充
    fill(v.begin(),v.end(),100);
    
    for_each(v.begin(),v.end(),MyPrint());
} 

int main()
{
    test01();
    return 0;
}

常用集合算法 — set_intersection、set_union、set_difference

算法简介:

set_intersection(iterator beg1, iterator end1,iterator beg2, iteraor end2, iterator dest);   //求两个有序序列容器的交集 
set_union(iterator beg1, iterator end1,iterator beg2, iteraor end2, iterator dest);  //求两个有序序列容器的并集
set_difference(iterator beg1, iterator end1,iterator beg2, iteraor end2, iterator dest);     //求两个容器的差集
//注意: 两个集合必须是有序序列
//beg1 容器1开始迭代器
//end1 容器1结束迭代器
//beg2 容器2开始迭代器
//end2 容器2结束迭代器
//dest 目标容器开始迭代器

示例:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;
//常用集合算法
//set_intersection   //求两个容器的交集
//set_union  //求两个容器的并集
//set_difference   //求两个容器的差集

class MyPrint
{
public:
    void operator()(int val)
    {
        cout << val <<"  ";
    }
};

void test01()
{
    vector<int>v1;
    vector<int>v2;
    for(int i = 0; i <10; i ++)
    {
        v1.push_back(i);
        v2.push_back(i + 5);
    }
    
    cout<<"集合v1:"<<endl;
    for_each(v1.begin(),v1.end(),MyPrint());
    cout << endl;
    cout<<"集合v2:"<<endl;
    for_each(v2.begin(),v2.end(),MyPrint());
    cout << endl;
    
    //目标容器需要提前开辟空间
    //set_intersection  求两个容器的交集
    //交集 开辟空间取小容器的size
    vector<int>vTargetInter;
    vTargetInter.resize(min(v1.size(),v2.size()));
    //获取交集 返回目标容器的最后一个元素的迭代器地址
    vector<int>::iterator itEnd = set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),vTargetInter.begin());
    cout<<"两容器交集为:"<<endl;
    for_each(vTargetInter.begin(),itEnd,MyPrint());  //用返回的迭代器末尾位置进行迭代
    cout << endl;
    
    //set_union  求两个容器的并集
    //开辟空间取两个容器size之和
    vector<int>vTargetUnion;
    vTargetUnion.resize(v1.size() + v2.size());
    itEnd = set_union(v1.begin(),v1.end(),v2.begin(),v2.end(),vTargetUnion.begin());    
    cout<<"两容器并集为:"<<endl;
    for_each(vTargetUnion.begin(),itEnd,MyPrint());  //用返回的迭代器末尾位置进行迭代   
    cout << endl;
    
    //set_difference  求两个容器的差集
    //开辟空间取两个容器size最大的
    vector<int>vTargetDiffer;
    vTargetDiffer.resize(max(v1.size(),v2.size()));
    itEnd = set_difference(v1.begin(),v1.end(),v2.begin(),v2.end(),vTargetDiffer.begin());    
    cout<<"v1和v2的差集为:"<<endl;
    for_each(vTargetDiffer.begin(),itEnd,MyPrint());  //用返回的迭代器末尾位置进行迭代   
    cout << endl;
    
    itEnd = set_difference(v2.begin(),v2.end(),v1.begin(),v1.end(),vTargetDiffer.begin());    
    cout<<"v2和v1的差集为:"<<endl;
    for_each(vTargetDiffer.begin(),itEnd,MyPrint());  //用返回的迭代器末尾位置进行迭代   
    cout << endl;
} 

int main()
{
    test01();
    return 0;
}

// output : 
//集合v1:
//0  1  2  3  4  5  6  7  8  9  
//集合v2:
//5  6  7  8  9  10  11  12  13  14  
//两容器交集为:
//5  6  7  8  9  
//两容器并集为:
//0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  
//v1和v2的差集为:
//0  1  2  3  4  
//v2和v1的差集为:
//10  11  12  13  14 

总结:
1、三种求集合方式,返回值是最后一个元素的位置
2、两个集合必须是有序序列
3、需要对目标容器开辟空间,交集取最小,并集相加,差集取最大

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值