13.1 multimap
multimap的应用
一个学生成绩录入和查询系统,接受以下两种输入:
Add name id score
Query score
name是个不超过16字符的字符串,中间没有空格,代表学生姓名。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
整个mp里没有分数比p低,p就指向begin,即:p==mp.begin()
若找到分数比p低,则:p!=mp.begin() ,p–即为低于p的最高分数。
接下来要找上述找到的score的所有相同分数
用一个迭代器maxp来记录p,maxID代表当前找到的分数是score的最大的id
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
struct StudentInfo {
int id;
char name[20];
};
struct Student {
//multimap中的元素按照first排序,并可以按first进行查找
int score; //因为关键字是分数,要按照分数排序
StudentInfo info;
};
//把student信息对应到multimap,并将里边成员变量的类型与first second对应好
//typedef用来定义类型
// 此后 MAP_STD 等价于 multimap<int,StudentInfo>
typedef multimap<int, StudentInfo> MAP_STD;
int main()
{
MAP_STD mp; //定义multimap的容器
Student st;
char cmd[20];
while (cin >> cmd)
{
if (cmd[0] == 'A') //Add name id score
{
cin >> st.info.name >> st.info.id >> st.score;
//st里面元素的类型与mp不同
//make_pair生成一个 pair<int,StudentInfo>变量
//其first 等于 st.score, second 等于 st.info
mp.insert(make_pair(st.score, st.info));
}
else if (cmd[0] == 'Q') //Query score
{
int score;
cin >> score;
//查等于score的学生用find,查比score成绩低的最高分用lower_bound,其返回值是[begin(),p) p即所找
MAP_STD::iterator p = mp.lower_bound(score);
//如果没有学生的分数比score,那么p的值为mp.begin(),不等于则找到了符合要求
if (p != mp.begin()) //有学生分数比他低
{
p--;
score = (*p).first; //比查询分数低的最高分
MAP_STD::iterator maxp = p; //用maxp迭代器记录
int maxID = (*p).second.id; //记录分数相同,学生id最大的id
for (; p != mp.begin() && (*p).first == score; --p)
{//遍历所有成绩和score相等的学生 从后往前走--p 只要p没有走到头并且分数是score
if ((*p).second.id > maxID) //如果id比记录的大,则更新
{
maxp = p;
maxID = (*p).second.id;
}
}
if (p->first == score)
{//如果上面循环是因为 p == mp.begin() 而终止,则p指向的元素还要处理
if ((*p).second.id > maxID)
{
maxp = p;
maxID = (*p).second.id;
}
}
cout << (*maxp).second.name << " " << (*maxp).second.id << " " << (*maxp).first << endl;
}
else lower_bound的结果就是 begin,说明没人分数比查询分数低
cout << "Nobody" << endl;
}
}
return 0;
}
13.2 map
#include <iostream>
#include <string>
#include <map>
using namespace std;
struct Student {
string name;
int score;
};
Student students[5] = {
{ "Jack",89 },{ "Tom",74 },{ "Cindy",87 },{ "Alysa",87 },{ "Micheal",98 }
};
typedef map<string, int> MP;
int main()
{
MP mp;
for (int i = 0; i < 5; ++i)
mp.insert(make_pair(students[i].name, students[i].score));
cout << mp["Jack"] << endl; // 输出 89
mp["Jack"] = 60; //修改名为"Jack"的元素的second
for (MP::iterator i = mp.begin(); i != mp.end(); ++i)
cout << "(" << (*i).first << "," << (*i).second << ")"; //输出:(Alysa,87) (Cindy,87) (Jack,60) (Micheal,98) (Tom,74)
cout << endl;
Student st;
st.name = "Jack";
st.score = 99;
pair<MP::iterator, bool> p = mp.insert(make_pair(st.name, st.score));
//这个pair相当于一个结构体p
//p.second判断是否插入成功 p.first是个迭代器,指向刚刚插入的元素 (*p.first).first取出那个元素的first
if (p.second)
cout << "(" << (*p.first).first << "," << (*p.first).second << ") inserted" << endl;
else
cout << "insertion failed" << endl;
mp["Harry"] = 78; //插入一元素,其first为"Harry",然后将其second改为78
MP::iterator q = mp.find("Harry");
cout << "(" << (*q).first << "," << (*q).second << ")" << endl; //输出 (Harry,78)
return 0;
}
map例题:单词词频统计程序
#include <iostream>
#include <string>
#include <map>
#include <set>
using namespace std;
struct Word {
int times;
string wd;
};
struct Rule {
bool operator()(const Word & w1, const Word &w2)const {
if (w1.times != w2.times)
return w1.times > w2.times;
else
return w1.wd < w2.wd;
}
};
int main()
{
string s; //s用来存放字符串
set<Word, Rule> st; //存放word类型变量 以Rule规格进行排序
map<string, int> mp; //first成员变量是string类型,即单词;second是int类型,表示次数;mp中是按照单词字典序从小到大排
while (cin >> s) //通过这个循环操作我们读入了所有单词并统计了使用次数
++mp[s];
//注意分析中括号 mp[s]是在找一个mp里面的元素
//如果这个元素的first成员变量是等于s,那么就会返回这个元素的second,++second即将单词的使用次数增加
//如果没有一个元素的first==s,那么就会向mp里添加一个元素,它的first==s,second==0,再++second
for (map<string, int>::iterator i = mp.begin(); i != mp.end(); ++i)
{
Word tmp;
tmp.wd = i->first;
tmp.times = i->second;
st.insert(tmp); //把这些东西插到st中,st中可以自动排序
}
//接下来遍历st并输出单词及次数
for (set<Word, Rule>::iterator i = st.begin(); i != st.end(); ++i)
cout << (*i).wd << " " << (*i).times << endl;
return 0;
}
我觉得最后这两章的内容有点难度啊,我有点乱了,我突然忘了set跟map都是干啥的了,我晕,继续加油吧