本文中的一些重要概念摘自C语言中文网
链接:http://c.biancheng.net/view/388.html

multimap 是一种关联容器,它的每一个元素都是一个键值对。容器中的元素是按关键字(也就是键的值)排好序的。允许有多个关键字的值相同。

同样,作为一个关联容器,我们不能随意更改关键字的值,因为它并不会自动给容器中的元素进行重新排序,因此想要修改容器中的值,应该先删除这个元素,再插入一个元素。

想要使用multimap就必须要包含头文件map

multimap中的元素都是pair模板类对象,把pair对象中的first当做键名,把second当做键值

multimap的成员函数
图片说明

注:find 和 count 不用==运算符比较两个关键字是否相等。如果x比y小和y比x小同时为假,就认为 x 和 y 相等。

了解了这些有用的成员函数之后呢,我们来看一下下面的例题:
例题:一个学生成绩录入和查询系统接受以下两种输入:

1) Add name id score
2) Query score

name 是一个字符串,其中不包含空格,表示学生姓名。id 是一个整数,表示学号。score 是一个双精度浮点数,表示分数。学号不会重复,分数和姓名都可能重复。

两种输入交替出现。
第一种输入表示要添加一个学生的信息,碰到这种输入,就记下学生的姓名、id 和分数。
第二种输入表示要查询分数为 score 的学生的信息,碰到这种输入,就输出已有记录中分数比查询分数低的最高分获得者的姓名、学号和分数。如果有多个学生满足条件,则输出学号最大的学生的信息。如果找不到满足条件的学生,则输出“Nobody”。

输入样例:
Add Jack 12 78
Query 78
Query 81
Add Percy 9 81
Add Marry 8 81
Query 82
Add Tom 11 79
Query 80
Query 81

输出结果样例:
Nobody
Jack 12 78
Percy 9 81
Tom 11 79
Tom 11 79

从题目要求中我们可以看到,这个业务对插入和查询操作需求量比较大,所以肯定不能用顺序容器,因为本身顺序容器是没有排好序的,进行查询操作会比较耗时,是O(n)的时间复杂度,同时由于顺序容器的内存是连续分配的,所以插入效率也不高。这时候我们就要想到关联容器了,由于这里的查找操作是根据分数score来进行的,而分数肯定是可以重复的,所以这时候我们要想到用multimap,让score做键名,让学号和姓名组成的结构做键值。

下面是实现的代码:

#include<iostream>
#include<string>
#include<map>

using namespace std;

class Student
{
    public:
        struct stu_info{ //C++支持在类中定义结构
            string name;
            int id;
        };

        Student() {}

        stu_info st;
        double score;
};

typedef multimap<double, Student> Stu_info;

int main()
{
    Stu_info students;
    string cmd;
    while(cin >> cmd)
    {
        if(cmd == "Add")
        {
            Student student;
            cin >> student.st.name >> student.st.id >> student.score;
            pair<double, Student> s(student.score, student);
            students.insert(s); 
        }
        else if(cmd == "Query")
        {
            double sco = 0;
            cin >> sco;
            Stu_info::iterator i = students.lower_bound(sco);
            if(i != students.begin())
            {
                --i;
                Stu_info::iterator maxp = i;
                int maxid = i->second.st.id;
                for(; i != students.begin() && i->first == sco; --i)
                {
                    if(i->second.st.id > maxid)
                    {
                        maxid = i->second.st.id;
                        maxp = i;
                    }
                }

                if(i->first == sco)
                {
                    maxp = i;
                    maxid = i->second.st.id;
                }

                cout << maxp->second.st.name << " " << maxp->second.st.id 
                    << " " << maxp->first << endl;

            }
            else
            {
                cout << "Nobody" << endl;
            }
        }
    }
    return 0;
}

例题的输出结果:
图片说明

本节完