在“学生”容器中作统计
在这个例子里面,我们将利用STL的容器,创建一个“学生”容器,并在其中利用STL的算法,通过STL的迭代器作用于容器,从而作一些统计工作。
下面这个例子能够完全看懂即可,如果想要上手写一遍,注意补全各种类型的定义。
学生的类型
一下是一个简单的学生类型,这将是我们要放在容器中的数据。下面的类的定义是不完备的,只列出了后续需要用到的部分,省略的部分可自行补充。
复制 class Student
{
private :
int no;
string name;
Sex sex;
string birth_place;
Major major;
// ......
public :
// ......
int get_no () { return no; }
string get_name () { return name; }
int get_sex () { return sex; }
Major get_major () { return major; }
display ();
// ......
};
需求及实现
建立“学生”容器
复制 vector < Student > students; // 创建学生容器
while (...) // 循环输入每个学生信息并放入容器
{
Student st;
...... // 输入一个学生信息到st
students . push_back (st); // 把st数据放入容器
}
容器元素按“学号由小到大”排序
复制 bool compare_no ( Student & st1 , Student & st2)
{
return st1 . get_no () < st2 . get_no ();
}
复制 sort ( students . begin () , students . end () , compare_no);
显示每个学生的信息
复制 void display ( Student & st) //显示st的信息
{
st . display ();
cout << endl;
}
复制 for_each ( students . begin () , students . end () , display);
统计“计算机”专业的人数
复制 bool match_major ( Student & st) { return st . get_major () == COMPUTER; }
复制 cout << count_if ( students . begin () , students . end () , match_major);
统计物理专业的人数呢?
复制 bool match_major2 ( Student & st) { return st . get_major () == PHYSICS; }
复制 cout << count_if ( students . begin () , students . end () , match_major2);
再统计“XXX”专业的人数呢?
这里稍微拓展一下仿函数(Functor) 的使用,在后续会有详细的介绍。
定义函数对象类如下:
复制 class MatchMajor
{
Major major;
public :
MatchMajor (Major m) { major = m; }
bool operator ()( Student & st) { return st . get_major () == major; }
};
下面就可以这样使用了:
复制 count_if ( students . begin () , students . end () , MatchMajor (COMPUTER));
count_if ( students . begin () , students . end () , MatchMajor (PHYSICS));
// 统计XXX专业的人数
count_if ( students . begin () , students . end () , MatchMajor (XXX));
类似的,统计“XXX”专业男生/女生的人数 :
复制 class MatchMajorAndSex
{
Major major;
Sex sex;
public :
MatchMajorAndSex ( Major m , Sex s) { major = m; sex = s; }
bool operator ()( Student & st)
{
return st . get_major () == major && st . get_sex () == sex;
}
};
复制 // 计算机女生
count_if ( students . begin () , students . end () , MatchMajorAndSex (COMPUTER , FEMALE));
// 物理男生
count_if ( students . begin () , students . end () , MatchMajorAndSex (PHYSICS , MALE));
编译器隐式地为之定义类(重载了函数调用操作符)和创建函数对象。
比如说:
复制 //统计“计算机专业女生”的人数
cout << "计算机专业女生的人数是:"
<< count_if ( students . begin () , students . end () ,
[]( Student & st) { return ( st . get_major () == COMPUTER)
&& ( st . get_sex () == FEMALE); });
//统计出生地为"南京籍计算机专业"的学生人数
cout << "出生地为\"南京\"的学生人数是:"
<< count_if ( students . begin () , students . end () ,
[]( Student & st) { return ( st . get_major () == COMPUTER)
&& ( st . get_birth_place () . find ( "南京" ) != string :: npos);});
//按“学号由小到大”对students的元素进行排序
sort ( students . begin () , students . end () ,
[]( Student & st1 , Student & st2) {
return st1 . get_no () < st2 . get_no ();});
//按“姓名由小到大”对students的元素进行排序
sort ( students . begin () , students . end () ,
[]( Student & st1 , Student & st2) {
return st1 . get_name () < st2 . get_name ();});
至此,读者应当对于C++STL的整体用法有了基本的掌握。在告知接口或者API的情况下,应当能够正确得使用STL了。