STL_04: 仿函数

STL_04: 仿函数

0x00 仿函数

仿函数的主要功能是为了搭配STL算法使用,单独使用仿函数的情况比较少。
仿函数(functors)在C++标准中采用的名称是函数对象(function objects)。仿函数主要用于STL中的算法中,虽然函数指针虽然也可以作为算法的参数,但是函数指针不能满足STL对抽象性的要求,也不能满足软件积木的要求–函数指针无法和STL其他组件搭配,产生更灵活变化。仿函数本质就是类重载了一个operator(),创建一个行为类似函数的对象。

对于重载了()操作符的类,可以实现类似函数调用的过程,所以叫做仿函数,实际上仿函数对象仅仅占用1字节,因为内部没有数据成员,仅仅是一个重载的方法而已。实际上可以通过传递函数指针实现类似的功能,但是为了和STL内部配合使用,它提供了仿函数的特性。


0x01 仿函数使用

1.1 C语言的处理方式

使用函数指针和回调函数来实现代码复用。例如qsort()

先介绍下qsort, C 库函数 - qsort()

#include <stdlib.h>
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
参数
base -- 指向要排序的数组的第一个元素的指针。
nitems -- 由 base 指向的数组中元素的个数。
size -- 数组中每个元素的大小,以字节为单位。
compar -- 用来比较两个元素的函数。
    
compar
Pointer to a function that compares two elements.
This function is called repeatedly by qsort to compare two elements. It shall follow the following prototype:
int compar (const void* p1, const void* p2);
Taking two pointers as arguments (both converted to const void*). The function defines the order of the elements by returning (in a stable and transitive manner):
return value	meaning
<0	The element pointed to by p1 goes before the element pointed to by p2
0	The element pointed to by p1 is equivalent to the element pointed to by p2
>0	The element pointed to by p1 goes after the element pointed to by p2
    
如果 compar 返回值小于 0< 0),那么 p1 所指向元素会被排在p2所指向元素的前面
如果 compar 返回值等于 0= 0),那么 p1 所指向元素与 p2所指向元素的顺序不确定,
如果 compar 返回值大于 0> 0),那么 p1 所指向元素会被排在 p2 所指向元素的后面。
    
compar函数实现等效如下:
int compareMyType (const void * a, const void * b)
{
  if ( *(MyType*)a <  *(MyType*)b ) return -1;
  if ( *(MyType*)a == *(MyType*)b ) return 0;
  if ( *(MyType*)a >  *(MyType*)b ) return 1;
}
#include <stdio.h>
#include <stdlib.h>

int values[] = { 88, 56, 100, 2, 25 };

int cmpfunc (const void * a, const void * b)
{
   return ( *(int*)a - *(int*)b );
}

int main()
{
   int n;

   printf("排序之前的列表:\n");
   for( n = 0 ; n < 5; n++ ) {
      printf("%d ", values[n]);
   }

   qsort(values, 5, sizeof(int), cmpfunc);

   printf("\n排序之后的列表:\n");
   for( n = 0 ; n < 5; n++ ) {
      printf("%d ", values[n]);
   }
  
  return(0);
}
/*
 * 程序输出:
 * 排序之前的列表:
 * 88 56 100 2 25 
 * 排序之后的列表:
 * 2 25 56 88 100
 *
*/

1.2 C++语言的处理方式

函数指针方式
#include <iostream>  
#include <algorithm>  
using namespace std;  
inline bool mysort(int a,int b){
    return a > b;
}
inline void print(int a){
  cout << a << endl;
} 
int main() {  
    int arr[5] = { 88, 56, 100, 2, 25 }; 
    sort(arr, arr+5,mysort);  
    for_each(arr,arr+5,print);
    return 0;   
}
函数模板方式
/*********************************************************************************************
    *  @Copyright (c) , All rights reserved.
    *  @file:       main.cpp
    *  @version:    ver 1.0
    *  @author:   zbb
    *  @brief:  
    *  @change:
    *  @email: 	binbin_erices@163.com
    *  Date             Version    Changed By      Changes 
    *  2020/3/28 23:50    1.0       zbb             create
**********************************************************************************************/
#include <iostream>  
#include <algorithm>  

using namespace std;

template<class T>
inline bool mysort(T const& a, T const& b) {
	return a > b;
}
template<class T>
inline void print(T a) {
	cout << a << endl;
}
int main() {
	int arr[5] = { 88, 56, 100, 2, 25 };
	sort(arr, arr + 5, mysort<int>);
	for_each(arr, arr + 5, print<int>);

	system("pause");
	return 0;
}
仿函数方式
/*********************************************************************************************
    *  @Copyright (c) , All rights reserved.
    *  @file:       main.cpp
    *  @version:    ver 1.0
    *  @author:   zbb
    *  @brief:  
    *  @change:
    *  @email: 	binbin_erices@163.com
    *  Date             Version    Changed By      Changes 
    *  2020/3/28 23:50    1.0       zbb             create
**********************************************************************************************/
#include <iostream>  
#include <algorithm>  

using namespace std;

class mysort {
public:
	bool operator()(int a, int b) const {
		return a > b;
	}
};

class print {
public:
	void operator()(int a) const {
		cout << a << endl;
	}
};
int main()
{
	int arr[5] = { 88, 56, 100, 2, 25 };
	sort(arr, arr + 5, mysort());
	for_each(arr, arr + 5, print());
	system("pause");
	return 0;
}
仿函数模板方式
/*********************************************************************************************
    *  @Copyright (c) , All rights reserved.
    *  @file:       main.cpp
    *  @version:    ver 1.0
    *  @author:   zbb
    *  @brief:  
    *  @change:
    *  @email: 	binbin_erices@163.com
    *  Date             Version    Changed By      Changes 
    *  2020/3/28 23:50    1.0       zbb             create
**********************************************************************************************/
#include <iostream>  
#include <algorithm>  

using namespace std;

template<class T>
class mysort {
public:
	inline bool operator()(const T& a, const T& b) const {
		return a > b;
	}
};
template<class T>
class print {
public:
	inline void operator()(const T& a) const {
		cout << a << endl;
	}
};

int main()
{
	int arr[5] = { 88, 56, 100, 2, 25 };
	sort(arr, arr + 5, mysort<int>());
	for_each(arr, arr + 5, print<int>());
	system("pause");
	return 0;
}

1.3 剑指Offer 把数组排成最小的数

题解链接

题解中使用的是仿函数方式,在这里使用函数模板方式

class Solution {
public:
    template<class T>
    static bool mycompare(const T& a, const T& b)
    {
        if (to_string(a)+to_string(b) < to_string(b)+to_string(a))
            return true;
        return false;
    }
 
    string printMinNumber(vector<int>& nums) {
        std::sort(nums.begin(), nums.end(), mycompare<int>);
        
        string res;
        for(auto i: nums)
        {
            res+=to_string(i);
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Erice_s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值