STL标准库(五) 算法,伪函数与空间适配器

伪函数

仿函数:像函数但不是函数,一般有两种形式struct或class

struct或class之所以能够进行仿函数的编写是因为他们可以进行()的运算符重载

int Min(int nNumberA, int nNumberB) 这是一个函数

{

    return nNumberA < nNumberB ? nNumberA : nNumberB;

}

以下一个程序进行演示:

当仿函数是stuct形式时:

struct sMin

{

    int operator()(int nNumberA, int nNumberB)

    {

       return nNumberA < nNumberB ? nNumberA : nNumberB;

    }

}; 该种形式实现了上述函数类似的功能

当仿函数是class形式时:

class cMin

{

public:

    int operator()(int nNumberA, int nNumberB)

    {

       return nNumberA < nNumberB ? nNumberA : nNumberB;

    }

int main()

{

    std::cout << Min(50, 100) << std::endl;

    struct sMin objs;

    std::cout << objs(50, 100) << std::endl; 结构体形式仿函数的第一种调用

    std::cout << sMin()(50, 100) << std::endl; 结构体形式仿函数的第二种调用

    std::cout << cMin()(50, 100) << std::endl; 类形式仿函数的调用

    return 0;

}

空间适配器

空间适配器顾名思义就是取分配回收内存空间,具有可以分为两种行为,一种针对普通变量。一种针对类

下面以一个程序演示讲解

class MyClass

{

public:

    MyClass()

{

    std::cout << "MyClass" << std::endl;

}

    MyClass(int opt) :nNumber(opt) {};

    ~MyClass()

{

    std::cout << "~MyClass" << std::endl;

}

public:

    int nNumber;

};

int main()

{

空间适配器对普通变量的应用:

    std::allocator<int> obj;  定义一个空间适配器

    int * p = obj.allocate(1); 利用空间适配器进行分配空间,()中的数字代表要分配的定义的类型的空间大小,此处分配一个int类型内存空间

    obj.construct(p, 12138); 利用空间适配器构造一个变量并赋值

    std::cout << *p << std::endl; 打印12138,可以正常使用

    *p = 100; 也可以解引用修改值

    std::cout << *p << std::endl;  同样也可以正常打印

    int *nAddr = obj.address(*p);  利用空间适配器设置两个内存指向相同类型的对象

    std::cout << nAddr << "\t" << p << std::endl; 两个指针指向同一个位置

    int Temp = 500;

    int *nAddr = obj.address(Temp); 这种形式类似于上述方法,两个变量

内存同样指向同一内存地址

    std::cout << nAddr << "\t" << *nAddr << std::endl; 打印该变量地址及数据

以上两种空间适配器的应用类似于申请引用

    std::cout << obj.max_size() << std::endl; 可以获取空间支配器最大的大小

    obj.deallocate(p, 1); p伪分配内存的对象,1为要回收内存的大小,用于回收该空间适配器分配

的对象内存大小

空间适配器对类的应用:

    std::allocator<MyClass> objc; 申请了一个类的类型的空间适配器

    MyClass * tObj = objc.allocate(1); 创建一个类对象并利用空间适配器申请内存

    objc.construct(tObj, 12138); 利用空间适配器进行构造类对象

    std::cout << tObj->nNumber << std::endl;

    objc.destroy(tObj); 销毁类对象

    objc.deallocate(tObj, 1);  回收内存

    system("pause");

    return 0;

}

算法

#include <algorithm> 需要包含的头文件

#include <vector> 该程序以vector做演示

struct Func 定义一个仿函数

{

    bool operator()(int nNumber)

    {

       return nNumber == 6;

    }

};

bool Fun5(int nNumber)一 个普通函数

{

    return nNumber == 5;

}

void print(int nNumber) 一个普通函数

{

    std::cout << nNumber << "\t";

}

int main()

{

    查找元素方式:

    std::vector<int> vec = { 1,2,3,4,5 }; 定义一个动态数组

    auto it = std::find(vec.begin(), vec.end(), 6); 搜索元素,参数依次开始位置,结束位置,搜索的元素。若找到则返回查找元素的迭代器,否则返回尾元素的迭代器   

if (it != vec.end())  可以以此方法判断是否搜索成功

    {

       std::cout << "success!" << "\t" << *it << std::endl;

    }

    else

    {

       std::cout << "failed!" << std::endl;

    }

    auto it = std::find_if(vec.begin(), vec.end(), Func()); 另一种查找算法,第三个参数是仿函数。原理是从某迭代器开始到某迭代器结束,取出某迭代器指向的值,利用仿函数进行判断,仿函数返回的ture或false返回给find_if,根据返回数值,find_if返回某迭代器,同find一样

    auto it = std::find_if(vec.begin(), vec.end(), Fun5); 第三个参数同样也可以是普通函数,但放入的是该函数的地址

    std::vector<int> vec2 = { 2,3 };

    auto it = std::find_first_of(vec.begin(), vec.end(), vec2.begin(), vec2.end()); 两个容器的查找,利用迭代器,后一个容器要从前一个容器范围内查找后一个容器元素的值。该方法只要找到其中一个元素便结束

auto it = std::search(vec.begin(), vec.end(), vec2.begin(), vec2.end()); 同上一个算法一样,但该方法要全部找到才会停止

    auto it = std::search_n(vec.begin(), vec.end(), 4, 2); 后两个参数表示要找到几个连续的几,全部找到则返回迭代器

    std::count(vec.begin(), vec.end(),2) 计算两迭代器指向元素范围内2出现的次数

    std::cout << std::count_if(vec.begin(), vec.end(), fun) << std::endl;   同查找的find_if一致,利用一个函数进行查找

排序:

    std::sort(vec.begin(), vec.end()); 对指定范围元素进行从小到大排序

    std::sort(vec.begin(), vec.end(),std::greater<int>()); 从大到小排序

    std::for_each(vec.begin(), vec.end(), print); 一种新的for循环,范围内元素依次传入第三个参数即一个函数中,该行代码是对该容器进行一个遍历打印

如果对堆进行排序:

    std::make_heap(vec.begin(), vec.end(), std::greater<int>()); 构造一个小端堆,如果没有std::greater<int>()则大端堆

    std::sort_heap(vec.begin(), vec.end(), std::greater<int>()); 从大到小排列

    std::replace(vec.begin(), vec.end(), 3, 12138);指定范围将3都替换尾12318

    std::fill(vec.begin(), vec.end(), 12138);指定范围元素都替换12138

std::remove(vec.begin(), vec.end(), 12138);删除范围内所有12138

    std::reverse(vec.begin(), vec.end());指定范围内逆向排序

    system("pause");

    return 0;

}

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值