Sort函数是一个比较方便使用的STL函数,可以直接来进行各种排序。
由于在工作的时候有一个排序,刚开始没怎么注意!就用sort算法来实现了,后来出现了一些问题才导致我才对sort算法的一些注意事项的总结:
1. sort 算法函数的用法。
vector<int> vect;
//….
Sort(vect.begin(),vect.end();
//相当于下面的调用
Sort(vect.begin(),vect.end(),less<int>()); //如果不提供比较函数是系统默认从小到大排序
当我们要按某种方式进行排序时,需要指定自己的排序函数,否则系统默认提供一个比较函数。
2.Sort用法挺简单,不过在这儿打算介绍一下值得注意的一点地方。
看下面程序(1):
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class A
{
public:
A()
{
dict.push_back("owen");
dict.push_back("messi");
dict.push_back("figo");
}
int less(const string &s1, const string &s2)
{
return s1 < s2;
}
void Sort()
{
sort(dict.begin(), dict.end(), less);
}
void output()
{
for(vector<string>::iterator iter=dict.begin(); iter !=dict.end(); ++iter)
cout << *iter << endl;
}
private:
vector<string> dict;
};
int main() {
A myclass;
myclass.output();
myclass.Sort();
myclass.output();
return 0;
}
编译的时候就报错。Why?难道不是这么用的。。。。
下面我们来看看 正确的例子(2):
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int less(const string &s1,const string &s2)
{
return s1<s2;
}
class A
{
public:
A()
{
dict.push_back("owen");
dict.push_back("messi");
dict.push_back("figo");
}
void Sort()
{
sort(dict.begin(), dict.end(), less);
}
void output()
{
for(vector<string>::iterator iter=dict.begin(); iter !=dict.end(); ++iter)
cout << *iter << endl;
}
private:
vector<string> dict;
};
int main() {
A myclass;
myclass.output();
myclass.Sort();
myclass.output();
return 0;
}
这个例子是正确的! 为什么有这个差异?这个问题出在哪儿,思考下上面两个例子的不同! 也许你不难发现其中的问题?this指针!!
例(1)中发现 int less(const string &s1, const string &s2)也就相当于int less( A* const this,const string &s1,const string &s2) 所以问题的答案一目了然!所以有两种解决方法:
1) 利用类的静态函数---面向类的属性、。
2) 利用仿函数来实现比较函数。
以上两种方法都巧妙的避开了this指针。当然以上部分还是为了解决下面的话题! 如果有这样的一个类 A中有成员int x.而类B 中有成员vector<A> vec.map<int,类C>mapVec .这样的情况对vector<A>vec,以A中的X 作为map表的索引排序。
类A int x;
类C int y;l
类B map<int,C>mapVec; vector<A> vec;对vector<A>用sort算法排序,其中A作为map表的索引查找C 类中的Y来进行排序。这儿问题就来了?如上面所说在B类中的Sort()-中的 sort()函数的比较函数如何写? 我们来看下伪代码:
Class A{
public:
Int x;
};
Class C{
public:
Int y;
};
Class B{
Public:
B(){};
Void Sort()
{
Sort(vec.begin(),vec.end(),比较函数);
}
private:
Vector<A> vec;
Map<int,C> mapVec;
};
当然看到这个问题也许第一影响应该是在Sort()中做一个快排就可以,当然这样可以。不过让我们结合上面的例子想想这个问题如果用纯STL的方法如何解决。
1. 利用类的静态函数-----这个方法当然不行。静态函数是类的属性而我们需要map表。
2. 利用仿函数来解决。
那这个仿函数如何来写?---仿函数中需要有map<int,C>表,且不能是通过this指针带入的。好了基于上面的我们来看下例子3:
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
class A
{
public:
int x;
};
class C//XXX
{
public:
int y;
};
class B
{
public:
B():cmp(mapVec)
{
}
void Sort()
{
sort(vec.begin(),vec.end(),cmp);
}
protected:
class InnerCmp
{
public:
InnerCmp(map<int,C> &map):m(map)
{
}
bool operator() (const A &a,const A &b) const
{
return m[a.x].y<m[b.x].y;
}
private:
map<int,C> &m;
};
private:
const InnerCmp cmp;
vector<A> vec;
map<int,C> mapVec;
};
int main()
{
return 0;
}
如上面的例子,我们构造的仿函数完全符合规则。同时巧妙的把map 放到类InnerCmp中。这样我们就可以达到上面问题的目的。当然这样做只是为了更好的理解 比较函数。用好sort函数