您的位置:首页 > 编程语言

STL伪函数应用

2016-04-13 13:30 316 查看
我们先来看一个剑指offer中的编程练习题吧:

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

这个编程练习并不难,有两个关键点:

①在于int和string之间的转换方便排序;

②在排序时要完成两个记录的全排列再比较。

看到在排序时需要特殊操作,我们完全可以借助STL提供的sort函数完成我们需要的操作

具体代码如下:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

bool cmp(string st1, string st2)
{
string s1 = st1 + st2;
string s2 = st2 + st1;
return s1 < s2;
}

string PrintMinNumber(vector<int> numbers) {
string result;
if (numbers.size() == 0)
return result;
vector<string> strNum;
for (int i = 0; i<numbers.size(); i++)     //完成转换
{
strNum.push_back(to_string(numbers[i]));
}
sort(strNum.begin(), strNum.end(),cmp );   //根据特定规则排序
for (int i = 0; i<numbers.size(); i++)
{
result += strNum[i];
}
return result;
};

int main()
{
vector<int> temp = { 3, 32, 321 };
string res = PrintMinNumber(temp);
cout << res << endl;
cin.sync();
cin.get();
return 0;

}




很容易就得到我们需要的答案。

然而我们习惯将函数封装在类中,因此我们将程序修改为

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

class Solution {
public:

bool cmp(string st1, string st2)
{
string s1 = st1 + st2;
string s2 = st2 + st1;
return s1 < s2;
}

string PrintMinNumber(vector<int> numbers) {
string result;
if (numbers.size() == 0)
return result;
vector<string> strNum;
for (int i = 0; i<numbers.size(); i++){
strNum.push_back(to_string(numbers[i]));
}
sort(strNum.begin(), strNum.end(),cmp );
for (int i = 0; i<numbers.size(); i++)
{
result += strNum[i];
}
return result;
}

};
int main()
{
vector<int> temp = { 3, 32, 321 };
Solution a;
string res=a.PrintMinNumber(temp);
//string res = PrintMinNumber(temp);
cout << res << endl;
cin.sync();
cin.get();
return 0;

}


然而这样是的结果是

error C3867: “Solution::cmp”: 函数调用缺少参数列表;请使用“&Solution::cmp”创建指向成员的指针

那么问题的原因在于,我们在使用STL泛类编程的过程中,对容器中的元素要进行批量操作,确实可以通过指针完成,但是这有极大的弊端,那就是必须指定参数以及返回类型,而这对于STL来说是违反泛类编程的本质思想的。

好像扯远了

直接说对于上面两段代码 根本区别在于这里

sort(strNum.begin(), strNum.end(),cmp );


cmp的类型应该是:

①函数对象(伪函数);

②全局指针。

在第二段代码中,将cmp封装在Solution类中,cmp不在是全局函数指针,因此出现了参数不匹配的情况。

对此啊,有两种处理方法

①将cmp方法改为静态成员即可;

static bool cmp(string st1, string st2)


②使用伪函数代替成员函数

什么是伪函数(functor)?函数对象是一种介于对象和函数之间的一个东西,调用方式和函数一样,但是调用的却是对象里的operator ()操作符,这可以给程序带来三大好处。

第一,面相对象里的模板机制对functor是完全适用的,因此用函数对象可以和STL完全兼容,换句话说,使用functor和泛型的思想相符。

第二,函数对象本质上是对象,因此,一个函数对象可以使用类中所封装的所有数据,而对于函数指针来说,只能使用全局数据,所以,使用functor可以达到数据封装的目的。

第三,functor往往是轻量级代码,因此,可以完美内联化,这对于程序效率的提升是非常有利的。

说了这么多 看看这段代码该怎么改很容易就理解的

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

class Solution {
public:

struct compare{                         //伪函数
bool operator()(string st1, string st2)
{
string s1 = st1 + st2;
string s2 = st2 + st1;
return s1 < s2;
}
};

string PrintMinNumber(vector<int> numbers) {
string result;
if (numbers.size() == 0)
return result;
vector<string> strNum;
for (int i = 0; i<numbers.size(); i++){
strNum.push_back(to_string(numbers[i]));
}
sort(strNum.begin(), strNum.end(),Solution::compare() );
for (int i = 0; i<numbers.size(); i++)
{
result += strNum[i];
}
return result;
}

};
int main()
{
vector<int> temp = { 3, 32, 321 };
Solution a;
string res=a.PrintMinNumber(temp);
//string res = PrintMinNumber(temp);
cout << res << endl;
cin.sync();
cin.get();
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编程 伪函数