本例演示了对list的特殊排序方法。
编程需求:
在原有代码基础进行更新,
需要对list进行排序,list保存的是指针,而排序的依据为指针指向对象的某一个属性。
分析:
list本身包含有sort方法,但是并不能满足要求,其排序方法是使用其元素的比较方法(<)进行比较排序,
如果list内部保存为对象,即可使用这个方法,但是,由于保存内容为指针,其按照指针大小进行比较,这并不是我们想要的结果。
同时,可以考虑利用标准sort方法: sort(list.begin(), list.end(), function), function为比较方法,但是,这是存在问题的,因为list不支持随机存储,就不能调用泛型编程的sort。
同时,可以考虑使用vector,可以达到我们的要求,但是,由于已有代码的原因,把list替换为vector代价比较高,而且由于原设计采用list,使用vector可能引入其他操作细节的问题,再不得已情况下才会考虑实用vector进行替代。
解决方法:
由于list的sort有重载方法:sort(greater);
greater是一个模版结构体。这个就是问题的解决关键。
========================================
由于编程需要,用到了stl的list的排序
但是排序又有特殊要求,并不能用list的默认排序方法(list.sort())。
本来打算用stl的泛型算法的sort
但是出现了这样的错误:list不支持stl 的泛型sort 算法,因为list不支持随机存储。
麻烦大了。
我的代码如下:
class MyTest
{
private:
int m_order;
int m_ID;
public:
MyTest(int clssID, int order):m_ID(clssID), m_order(order)
{
}
int GetOrder()
{
return m_order;
}
int GetID()
{
return m_ID;
}
};
int main(int argc, char* argv[])
{
list<MyTest*> testList;
// 向添加元素(MyTest指针)
.......
// 此处就是对testList进行排序,排序标准为 指针指向对象的order
// 在此处使用 testList.sort() 是不能达到要求的,其是按指针的值进行排序。
// 而且不能使用sort(testList.begin(), testList.end(), 比较方法 ); 因为list不支持随机存储。
// 如果为vector 就可以进行排序
return 0;
}
解决方案:
list的sort有重载方法,为sort(greater<>());
在此重写greater的特例就可以解决问题。
template<>
struct std::greater<MyTest*>
{
bool operator()( MyTest*_X, MyTest* _Y) const
{
return (_X->GetOrder() > _Y->GetOrder());
}
};
全部代码:
#include "stdafx.h"
#include <list>
#include <iostream>
#include <algorithm>
using namespace std;
class MyTest
{
private:
int m_order;
int m_ID;
public:
MyTest(int clssID, int order):m_ID(clssID), m_order(order)
{
}
int GetOrder()
{
return m_order;
}
int GetID()
{
return m_ID;
}
};
template<>
struct std::greater<MyTest*>
{
bool operator()( MyTest*_X, MyTest* _Y) const
{
return (_X->GetOrder() > _Y->GetOrder());
}
};
void TestOut(MyTest* p)
{
cout << p->GetOrder() << endl;
}
int main(int argc, char* argv[])
{
list<MyTest*> testList;
for(int i = 0; i < 10; i++)
{
testList.push_back(new MyTest(rand()%50),rand()%100);
}
testList.sort(greater<MyTest*>());
for_each(testList.begin(), testList.end(), TestOut);
return 0;
}
输出结果:
==============================
41
34
28
24
19
17
14
12
8
0
Press any key to continue
==============================
结果为降序排列(数值为随机数,多次运行出现结果可能不同)
但是如果我想要一个升序排列,就要把greater的内部重新实现,考虑到灵活性,我们把代码修改成这样:
enum GREATER_OP
//新增加枚举类型,标明排序方式。
{
GREATER_UP = 0,
GREATER_DOWN = 1
};
template<>
struct std::greater<MyTest*>
{
GREATER_OP op;
bool operator()( MyTest*_X, MyTest* _Y) const
{
bool retVal;
switch(op)
{
case GREATER_UP:
retVal = (_X->GetOrder() < _Y->GetOrder());
break;
case GREATER_DOWN:
retVal = (_X->GetOrder() > _Y->GetOrder());
break;
default:
retVal = (_X->GetOrder() > _Y->GetOrder());
}
return retVal;
}
};
现在代码是这个样子:
#include "stdafx.h"
#include <list>
#include <iostream>
#include <algorithm>
using namespace std;
class MyTest
{
private:
int m_order;
int m_ID;
public:
MyTest(int clssID, int order):m_ID(clssID), m_order(order)
{
}
int GetOrder()
{
return m_order;
}
int GetID()
{
return m_ID;
}
};
enum GREATER_OP
{
GREATER_UP = 0,
GREATER_DOWN = 1
};
template<>
struct std::greater<MyTest*>
{
GREATER_OP op;
bool operator()( MyTest*_X, MyTest* _Y) const
{
bool retVal;
switch(op)
{
case GREATER_UP:
retVal = (_X->GetOrder() < _Y->GetOrder());
break;
case GREATER_DOWN:
retVal = (_X->GetOrder() > _Y->GetOrder());
break;
default:
retVal = (_X->GetOrder() > _Y->GetOrder());
}
return retVal;
}
};
void TestOut(MyTest* p)
{
cout << p->GetOrder() << endl;
}
int main(int argc, char* argv[])
{
list<MyTest*> testList;
for(int i = 0; i < 10; i++)
{
testList.push_back(new MyTest(rand()%50, rand()%100));
}
greater<MyTest*>
my_Greater;
my_Greater.op = GREATER_UP;
testList.sort(my_Greater);
for_each(testList.begin(), testList.end(), TestOut);
cout << "=====================" << endl;
my_Greater.op = GREATER_DOWN;
testList.sort(my_Greater);
for_each(testList.begin(), testList.end(), TestOut);
return 0;
}
编程需求:
在原有代码基础进行更新,
需要对list进行排序,list保存的是指针,而排序的依据为指针指向对象的某一个属性。
分析:
list本身包含有sort方法,但是并不能满足要求,其排序方法是使用其元素的比较方法(<)进行比较排序,
如果list内部保存为对象,即可使用这个方法,但是,由于保存内容为指针,其按照指针大小进行比较,这并不是我们想要的结果。
同时,可以考虑利用标准sort方法: sort(list.begin(), list.end(), function), function为比较方法,但是,这是存在问题的,因为list不支持随机存储,就不能调用泛型编程的sort。
同时,可以考虑使用vector,可以达到我们的要求,但是,由于已有代码的原因,把list替换为vector代价比较高,而且由于原设计采用list,使用vector可能引入其他操作细节的问题,再不得已情况下才会考虑实用vector进行替代。
解决方法:
由于list的sort有重载方法:sort(greater);
greater是一个模版结构体。这个就是问题的解决关键。
========================================
由于编程需要,用到了stl的list的排序
但是排序又有特殊要求,并不能用list的默认排序方法(list.sort())。
本来打算用stl的泛型算法的sort
但是出现了这样的错误:list不支持stl 的泛型sort 算法,因为list不支持随机存储。
麻烦大了。
我的代码如下:
class MyTest
{
private:
int m_order;
int m_ID;
public:
MyTest(int clssID, int order):m_ID(clssID), m_order(order)
{
}
int GetOrder()
{
return m_order;
}
int GetID()
{
return m_ID;
}
};
int main(int argc, char* argv[])
{
list<MyTest*> testList;
// 向添加元素(MyTest指针)
.......
// 此处就是对testList进行排序,排序标准为 指针指向对象的order
// 在此处使用 testList.sort() 是不能达到要求的,其是按指针的值进行排序。
// 而且不能使用sort(testList.begin(), testList.end(), 比较方法 ); 因为list不支持随机存储。
// 如果为vector 就可以进行排序
return 0;
}
解决方案:
list的sort有重载方法,为sort(greater<>());
在此重写greater的特例就可以解决问题。
template<>
struct std::greater<MyTest*>
{
bool operator()( MyTest*_X, MyTest* _Y) const
{
return (_X->GetOrder() > _Y->GetOrder());
}
};
全部代码:
#include "stdafx.h"
#include <list>
#include <iostream>
#include <algorithm>
using namespace std;
class MyTest
{
private:
int m_order;
int m_ID;
public:
MyTest(int clssID, int order):m_ID(clssID), m_order(order)
{
}
int GetOrder()
{
return m_order;
}
int GetID()
{
return m_ID;
}
};
template<>
struct std::greater<MyTest*>
{
bool operator()( MyTest*_X, MyTest* _Y) const
{
return (_X->GetOrder() > _Y->GetOrder());
}
};
void TestOut(MyTest* p)
{
cout << p->GetOrder() << endl;
}
int main(int argc, char* argv[])
{
list<MyTest*> testList;
for(int i = 0; i < 10; i++)
{
testList.push_back(new MyTest(rand()%50),rand()%100);
}
testList.sort(greater<MyTest*>());
for_each(testList.begin(), testList.end(), TestOut);
return 0;
}
输出结果:
==============================
41
34
28
24
19
17
14
12
8
0
Press any key to continue
==============================
结果为降序排列(数值为随机数,多次运行出现结果可能不同)
但是如果我想要一个升序排列,就要把greater的内部重新实现,考虑到灵活性,我们把代码修改成这样:
enum GREATER_OP
//新增加枚举类型,标明排序方式。
{
GREATER_UP = 0,
GREATER_DOWN = 1
};
template<>
struct std::greater<MyTest*>
{
GREATER_OP op;
bool operator()( MyTest*_X, MyTest* _Y) const
{
bool retVal;
switch(op)
{
case GREATER_UP:
retVal = (_X->GetOrder() < _Y->GetOrder());
break;
case GREATER_DOWN:
retVal = (_X->GetOrder() > _Y->GetOrder());
break;
default:
retVal = (_X->GetOrder() > _Y->GetOrder());
}
return retVal;
}
};
现在代码是这个样子:
#include "stdafx.h"
#include <list>
#include <iostream>
#include <algorithm>
using namespace std;
class MyTest
{
private:
int m_order;
int m_ID;
public:
MyTest(int clssID, int order):m_ID(clssID), m_order(order)
{
}
int GetOrder()
{
return m_order;
}
int GetID()
{
return m_ID;
}
};
enum GREATER_OP
{
GREATER_UP = 0,
GREATER_DOWN = 1
};
template<>
struct std::greater<MyTest*>
{
GREATER_OP op;
bool operator()( MyTest*_X, MyTest* _Y) const
{
bool retVal;
switch(op)
{
case GREATER_UP:
retVal = (_X->GetOrder() < _Y->GetOrder());
break;
case GREATER_DOWN:
retVal = (_X->GetOrder() > _Y->GetOrder());
break;
default:
retVal = (_X->GetOrder() > _Y->GetOrder());
}
return retVal;
}
};
void TestOut(MyTest* p)
{
cout << p->GetOrder() << endl;
}
int main(int argc, char* argv[])
{
list<MyTest*> testList;
for(int i = 0; i < 10; i++)
{
testList.push_back(new MyTest(rand()%50, rand()%100));
}
greater<MyTest*>
my_Greater;
my_Greater.op = GREATER_UP;
testList.sort(my_Greater);
for_each(testList.begin(), testList.end(), TestOut);
cout << "=====================" << endl;
my_Greater.op = GREATER_DOWN;
testList.sort(my_Greater);
for_each(testList.begin(), testList.end(), TestOut);
return 0;
}