Week 13——第一部分收官之战

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都是干啥的了,我晕,继续加油吧

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值