题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1004
题意
给你n个字符串,找出出现次数最多的那个字符串。
题解
运用map,将字符串作为key,出现的次数为value。找出最大value对应的key.
map基础知识
- 基本介绍:Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字(key),每个关键字只能在map中出现一次,第二个可能称为该关键字的值(value))的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。
下面举例说明什么是一对一的数据映射。比如一个班级中,每个学生的学号跟他的姓名就存在着一一映射的关系,这个模型用map可能轻易描述,很明显学号用int描述,姓名用字符串描述. -
映射
map就是从键(key)到值(value)的映射,因为重载了[]运算符,map与数组类似。
key和value类型任意;
key的值不允许重复,可以利用这个特点进行去重;
-
容器属性
联系: 关联容器中的元素被它们的键引用,而不是它们在容器中的绝对位置。
顺序:严格遵照字典序进行排序;
唯一的key值:容器中没有两个元素可以有相同的key;
- 向map中插入数据
Map["abc"]=1; //类似于数组;
Map.insert(pair<string,int>("c",3));
Map.insert(make_pair<string,int>("d",4)) ;以上三种用法,虽然都可以实现数据的插入,但是它们是有区别的,当然了第二种和第三种在效果上是完成一样的,用insert函数插入数据,在数据的插入上涉及到集合的唯一性这个概念,即当map中有这个关键字时,insert操作是插入数据不了的,但是用数组方式就不同了,它可以覆盖以前该关键字对应的值,
- 修改和查找数据:
修改Map["sunquan"]=11111;
查找数据 用Map.find(key); 可以通过键来查。
用find函数来定位数据出现位置它返回的一个迭代器 如果map中没有要查找的数据,它返回的迭代器等于end函数返 回的迭代器,当数据出现时,它返回数据所在位置的迭代器。用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了 -
#include<iostream> #include<map> #include<string> #include<algorithm> using namespace std; int main() { int num;//num个数; cin>>num; string a,b; map<string,int>mp; map<string,int>::iterator it; for(int i=1; i<num+1; i++) { cin>>a; //输入从那些东西里寻找 mp[a]; //放到map容器的key值里面; } cin>>b; //输入要查找的数据; if(mp.find(b)!=mp.end()) cout<<"YES"<<endl; else cout<<"NO"<<endl; return 0; }
- 删除元素:
通过key删除;
通过迭代器来删除;#include <iostream> #include <map> using namespace std; int main() { int n; cin>>n; string s; cin>>s; string tmp; map<string,int>mp; for(int i=0; i<n; ++i) { cin>>tmp; mp[tmp]; //存入key } if(mp.find(s)!=mp.end()) { mp.erase(s) ; //删除函数mp.erase() map<string,int>::iterator it; for(it=mp.begin(); it!=mp.end(); it++) { cout<<it->first<<" "; } } else { cout<<"song"<<endl; } return 0; }
- 使用迭代器遍历:
迭代器声明:map<string,int> ::iterator it; 尖括号里面的是类型名,iterator后面是迭代器名称。it->first:指向的是key的值;
it->second:指向的是key对应的映射的值;#include <iostream> #include <string> #include <map> #include <algorithm> using namespace std; map<string,int> mp; int main() { int n; string s; cin>> n; for(int i=1; i<=n; i++) { cin>> s; mp[s]; //存入key; } map<string,int>::iterator it; for(it=mp.begin(); it!=mp.end(); it++) { cout<< it->first << ' ' << it->second << endl; } }
- map常用函数
函数: begin() 返回指向map头部的迭代器 end() 返回指向map末尾的迭代器 rbegin() 返回一个指向map尾部的逆向迭代器 rend() 返回一个指向map头部的逆向迭代器 clear() 删除所有元素 empty() 如果map为空则返回true erase() 删除一个元素 find() 查找一个元素 count() 返回指定元素出现的次数 lower_bound() 返回键值>=给定元素的第一个位置 upper_bound() 返回键值>给定元素的第一个位置 insert()插入元素 size() 返回map中元素的个数 max_size()返回可以容纳的最大元素个数 swap() 交换两个map get_allocator() 返回map的配置器 equal_range() 返回特殊条目的迭代器对 max_size() 返回可以容纳的最大元素个数 key_comp() 返回比较元素key的函数 value_comp() 返回比较元素value的函数
-
AC Code(刚学完map,就去做题了,不怎么会用,就只用了之前的知识,看了学长的代码才知道了map如何去在题目中运用,用map写确实会比较简单些)
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <vector> #include <map> #include <stack> #include <queue> #include <functional> #include <algorithm> #define _USE_MATH_DEFINES using namespace std; typedef long long LL; struct Data { string s; int id; }; bool cmp(Data x, Data y) { return x.id > y.id; } int main() { int n; while(~scanf("%d",&n) && n) { string str; Data st[n+1]; for(int i=1; i<=n; i++) { st[i].id = 0; } int k = 0; for(int i=1; i<=n; i++) { cin>> str; int t = 0; int j; for(j=1; j<=k; j++) { if(str == st[j].s) { t = 1; break; } } if(t==0) { ++k; st[k].s = str; st[k].id++; } else { st[j].id++; } } sort(st+1, st+1+k, cmp); cout<< st[1].s << endl; } return 0; }
-
附上用map解决这道题的code
#include<string> #include<iostream> #include<map> #include<string> using namespace std; map<string,int>ma; string s,ans; int main() { int n; while(scanf("%d",&n)!=EOF&&n) { string s; for(int i=0;i<n;i++){ cin>>s; ma[s]++; //存入key,并使其对应value++;用value表示该字符串出现的次数 } int num=0; for(map<string,int>::iterator it=ma.begin();it!=ma.end();it++) { s=it->first; if(ma[s]>num) { ans=s; num=ma[s]; } } cout<<ans<<endl; ma.clear(); //注意,清空map. } return 0; }