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