map的几个题
Let the Balloon Rise
题意:
给你几个颜色的气球
,找出数量最多的颜色的气球是哪个
思路:
这题不用map也可以做,但拿来练练map很合适,熟悉一下map的用法
#include <iostream> #include <cstring> #include <algorithm> #include <string> #include <map> using namespace std; map<string, int>mp; map<string, int>::iterator it;//迭代器,用来表示mp里的每种字符串和数量 int main() { int n; string color ,ans; while (cin >> n , n) { mp.clear();//每次先清空一下mp,如果不清空,上次记录的就还在mp里 for (int i = 0; i < n; i++) { cin >> color; mp[color] ++;//注意map用法,就是这么用的,这里表示color这个颜色的数量加一 //比如输入 red 那么就表示 mp[red] 数量加一 } int maxnum = 0; //迭代器遍历整个map for(it = mp.begin() ; it != mp.end() ; it ++ )//这里如果写it < mp.end()会编译错误,只能是 != if (maxnum < it->second) { maxnum = it->second; ans = it->first; } cout << ans << endl; } return 0; }
https://ac.nowcoder.com/acm/contest/12794/B
题意:
给你几个莫名其妙的字母,表示一串字符串的缩写,比如wzs可以表示wo zhen shuai,后面是一个空格,之后跟的是这个缩写表示的完整形式,然后给你一段掺杂着这些缩写的信,如果遇到相应的缩写就把它替换成相应的完整形式。
思路:
这个题貌似用Python特别好做,但是c++的话我们就优先想到map
输入的时候:
在这个题我们学习一下两个c++<string>库里的函数,一个是getline,用法是getline(cin , 定义的字符串),由于cin一个字符串是遇到空格就停,所以这个getline作用是读取包括空格在内的一整行。
另一个是substr,用法是s = s.substr(下标),比如下标是1,那么就相当于把s等同于1下标之后的字符串,在这个题里作用就是去掉开头的空格。
而关于下面map的判断:
我们在这里需要判断每个单词是不是缩写,比如r就是缩写,而tell就不是缩写,由于每个单词都被空格或换行隔开了所以
更具体的思路是,在读入下面的信的时候,由于cin字符串的特性,使得每次遇到空格或者换行的时候就停止读入了,所以我们在读入的时候,先cin一个字符串,然后getchar掉后面的这个字符,判断这个字符是空格还是换行,放到一个while里,如果是空格,就是相当于输出一个单词在输出一个空格的形式,在while结束后,再输出一个换行。而注意的是,我们在getchar这个ch的时候,先随便给ch一个值,让这个单词先进入while,而cin字符串和getchar字符串都是在while里执行的。
#include <iostream> #include <string> #include <cstdio> #include <algorithm> #include <cmath> #include <queue> #include <map> using namespace std; int main() { map<string, string>mp; map<string, string>::iterator it; string s1, s2; int n1; cin >> n1; for (int i = 0; i < n1; i++) { cin >> s1; getline(cin, s2); s2 = s2.substr(1); mp[s1] = s2; } int n2; cin >> n2; char ch; for (int i = 0; i < n2; i++) { string s; ch = '1'; while (ch != '\n')//判断每个单词是否是缩写 { cin >> s; ch = getchar(); bool flag = false;//标记这个 s 在mp中是否有, for (it = mp.begin(); it != mp.end(); it++) { if (s == it->first) { cout << it->second << ' '; flag = true;//有就标记成true break; } } if (flag == false)//循环结束,如果s在mp中没有找到所对应的就是没有,直接输出s即可 cout << s << ' '; } cout << endl; } return 0; }
关于下面循环中这个bool 一个flag的问题,如果是直接写成下面这样的话:
for (it = mp.begin(); it != mp.end(); it++) { if (s == it->first) cout << it->second << ' '; else cout << s << ' '; }
看出问题了吗,它的输出结果是这样的

在这踩了个坑,唉,所以bool一个flag,循环结束后判断一下flag就防止了这种情况
PS:
而这个题我们也可以这么做:上一种做法是<string,string>的映射和 it 迭代器,我们其实也可以开两个map,第一个是<string,string>,用来映射缩写和完整形式,第二个是<string,int>,其中int这个映射用来标记下面给出的信中在上面是否有相应的缩写及其完整形式,如果所映射的int是0就没有,不是0就有,如果有就输出这个缩写的完整形式,如果没有就直接输出这个词。
具体做法看代码:
#include <iostream> #include <string> #include <cstdio> #include <algorithm> #include <cmath> #include <queue> #include <map> using namespace std; int main() { map<string , string>mp; map<string,int>msign; string s1, s2; int n1; cin >> n1; for (int i = 0; i < n1; i++) { cin >> s1; getline(cin , s2); s2 = s2.substr(1); mp[s1] = s2; msign[s1] = 1; } int n2; cin >> n2; char ch; for (int i = 0; i < n2; i++) { string s; ch = '1'; while(ch != '\n') { cin >> s; ch= getchar(); if(msign[s]==1)cout << mp[s] << ' ' ; else cout << s << ' '; } cout << endl; } return 0; }

浙公网安备 33010602011771号