前面在“STL中绑定器的使用” 一文中已经初步阐述了使用STL中的绑定器和函数对象实现对序列容器中的数据进行排序或者查找的方法,使用此方法能够写出优雅高效的代码。本文在原先的基础上作进一步的延伸,通过一个实际问题的使用情景,介绍使用“绑定器和函数对象嵌套调用”的方法在最少代码的基础上实现高效的功能。
问题:有一组电池,需要对其根据各自的参数和指标信息进行分组。参数和指标信息即是指电池的电压和放电时间,分组的基本思想是将彼此之间的的电压误差和放电时间误差分别在某个容许值范围内的电池归为一组 。
例如,有这样一组电池,每个电池均有唯一的编号,每个电池的电压值和放电时间均已测定,现在要讲这些电池按每三个一组来分类,每组中两两之间的电压误差不大于0.02,放电时间误差不大于1。
分析:这个问题的算法并不复杂,一般的处理思路就是先开一个数组或者链表存放组的信息,然后遍历每个电池,确定这个电池可以分配到已经存在的各个组中的哪一个,如果找到可以分配的组,则将电池分配到这个组中,同时开始下一个,否则,则新增一个组,并插入其中,并继续处理下一个电池。
如果我们不使用STL,而直接用C代码或者C++代码来书写,那么代码难免会显得冗长,抛开其他不谈,单单for循环都得有好几个,这其中还不考虑由于多方面的原因而带来的效率降低问题。而借助于STL中的绑定器和函数对象,我们可以用更简洁更优雅的代码来实现这个处理逻辑。
“ 源代码就是设计”,直接看代码。
先定义电池信息的基本结构,以及其他一些数据结构。
判断组是否可用的二元函数对象IsGroupAvailable 的实现:在重载其“()”操作符时,用find_if在组中查找是否超限的情况存在,如果找到超限的,则find_if的返回值即不等于end,注意在这里嵌套调用了另一个二元函数对象IsLimitExceed 来判断是否超限。
二元函数对象IsLimitExceed的实现如下:
有了判断当前电池信息是否可以分配到某个组中的关键代码,以及判断分组是否可用的代码,那么剩下的问题就很显而易见了,下面是自动分组的函数代码,其调用find_if,并传入应用了绑定器之后的函数对象IsGroupAvailable。
这样,整个逻辑的处理流程就已经完毕。可以看到,采用绑定器结合嵌套的函数对象调用的方式,写出来的代码更优雅。同时由于使用了标准的STL算法函数,还可以借助于编译器的优化来提高程序的性能。