作者yoco315 (眠月)
看板C_and_CPP
标题Re: [问题] 二维vector sort
时间Sun Oct 11 09:18:58 2009
※ 引述《dreamroyc ()》之铭言:
: 宣告方式是这个样子
: vector<vector<string> > input;
: 这当中我想以每一个阵列的第二个元素当作排序依据
: 如input[][1] 类似这样
你要传入自己的「比较准则」
我们可以写一个函数专门用来比较两个 vector<string> 的大小,
准则是比较这两个 vector<string> 的第一个元素,像是这样……
typedef vector<string> strvec ;
bool LessByElem_1(const strvec& v1, const strvec& v2) {
return v1[1] < v2[1] ;
}
然後把这个函数传给 sort,
这样 sort 就知道要以这个函数当作比较的准则
sort ( input.begin(), input.end(), LessByElem_1 ) ;
但是有(大部分)的 compilier 并不懂得将函数指标 inline,
所以上面这种写法在效能会比手工打造的排序函数吃亏一点点,
可是我们可以把这个比较准则设计成一个 class,
然後覆载这个 class 的 operator(),
这样这个 class 实体就是一个有着类似函数行为的 object
也就是一个 function object(functor),
像是这样……
struct LessByElem_1 {
bool operator()(const strvec& v1, const strvec&2) const {
return v1[1] < v2[1] ;
}
} ;
然後你就可以像这样使用这个 class
LessByElem_1 cmp ;
sort ( input.begin(), input.end(), cmp ) ;
或是直接这样
sort ( input.begin(), input.end(), LessByElem_1() ) ;
这样你就获得效能了,很好。
但是事情还可以更好。
使用 functor 的另外一个好处,
就是物件可以有 data member,可以有「状态」,
所以我们可以设定一个 functor 的行为。
假设有一天你突然想要依照第五个元素来排序你的 string vector,
那比较原始的作法就是你另外写了一个 class 叫做 LessByElem_4,
比较好的作法是我们扩充我们的 functor class 让他可以接受一个参数,
这样我们就可以弹性的指定这个 functor 要第几个元素来排序
struct LessByElem {
size_t idx_ ;
LessByElem(const size_t idx) idx_(idx) {}
bool operator()(const strvec& v1, const strvec& v2) const {
return v1[idx_] < v2[idx_] ;
}
} ;
sort ( input.begin(), input.end(), LessByElem(1) ) ; // 像这样
sort ( input.begin(), input.end(), LessByElem(4) ) ; // 或是这样
这下我们不仅有了效率,还有了弹性!这个程式码可以被用了!
还不赖!但是还没完美……因为这个 class 只能用在 vector<string>,
这有点可惜,因为以後你可能会想要对 vector<int> 作类似的事情,
所以让我们把这个 functor class 设计成 template。
struct LessByElem {
size_t idx_ ;
LessByElem(const size_t idx) idx_(idx) {}
template < typename T >
bool operator()(const T& v1, const T& v2) const {
return v1[idx_] < v2[idx_] ;
}
} ;
好啦,搞定了,ㄎㄎ。
--
To iterate is human, to recurse, divine.
递回只应天上有, 凡人该当用回圈. L. Peter Deutsch
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 118.160.104.161
1F:→ ADF:传函式进去不会影响效能八 10/11 11:41
2F:推 VictorTom:推....:) 10/11 12:40
3F:→ yoco315:ADF 自己测一下 10/11 14:29
4F:推 spir:好强 10/11 14:51
5F:推 dreamroyc:感谢你,我测试看看 10/11 15:27
6F:推 Cloud:注音文...科科 10/11 15:57
7F:推 Ebergies:传函式会多一个 function pointer, 在 compare 频繁呼叫 10/11 16:29
8F:→ Ebergies:时会对效能有不小的影响 10/11 16:30
9F:推 nowar100:漂亮 10/11 16:44
10F:推 holymars:idx_为什麽不写进template里 @@? 10/11 16:47
11F:推 legnaleurc:这样到时候 runtime 有机会改吧 我猜 10/11 16:58
12F:推 Cloud:映象中compiler会把functor做inline 10/11 17:19
13F:推 holymars:runtime有机会改..除非是有要写LessByElem(i)这种code XD 10/11 19:15
14F:推 lance7:太强了... 10/11 21:46
15F:推 elfkiller:推,非常实用 10/12 22:15
16F:推 ledia:依照第五个元素来排序 ..... 这是隐藏的哏吗 ? XD 10/12 23:15