考研复试系列——第十一节 map的使用

考研复试系列——第十一节 map的使用

前言

在考研上机试题中,还是经常出现一些类如词频统计的问题的,解决这类问题通常使用哈希表,在C++的STL当然提供了对其支持,比如c++中的hash_map。
在实际做题中,我们只需要使用map就OK了 。map与hashmap的用法基本一致,但底层实现是不同的,前者使用红黑树实现,后者使用哈希表实现。
当然在做题中直接map就足够了。所以这里只记录下map的使用方法。

map基础

#pragma warning(disable:4786)//消除4786警告
#include<iostream>
#include<string>
#include<map>

using namespace std;

int main()
{
	string str = "wangcan";
	reverse(str);
	map<string,int> mmap;
	//插入数据
	mmap.insert(map<string,int>::value_type("wang",10));
	mmap.insert(pair<string,int>("wwww",5));
	mmap.insert(make_pair<string,int>("cumt",77));
	mmap["csdn"] = 3;
	//查找数据
	int n = mmap["csdn"];
	map<string,int>::iterator iter;
	iter = mmap.find("csdn");//find返回一个迭代器
	int m = iter->second;//利用迭代器获取m的值
	for(iter=mmap.begin();iter!=mmap.end();iter++)//利用迭代器遍历
		cout<<iter->first<<":"<<iter->second<<endl;
	//修改数据
	mmap["csdn"] = 10;
	iter = mmap.find("csdn");
	iter->second = 10;
	return 0;
	//删除数据
	mmap.erase("cumt");//根据键值删除
	mmap.erase(iter);//利用迭代器删除
	mmap.clear();//清空所有
}

例题一

下面来一道以前做过的ACM的map的水题 。题目描述:
程序员Astar不仅热爱编程, 也热爱运动, 最近,他所在的公司准备组织大家开展一些体育活动, 在此之前希望了解每个人所喜欢的体育运动有哪些, 担任这次活动统计的程序员Astar要求参与投票的每个人写上自己最喜爱的3项体育运动, 并在最终结果中选出3项最受欢迎的(喜爱人数最多的前3名)作为这次活动准备开展的运动, 如果前3名中出现票数相同的, 则字母序较小的优先选择。

输入:输入的第一行有一个正整数n (n <= 100), 接下来的每一行有3个不相同的非空字符串(每个字符串只由小写字母构成, 且长度都不大于10), 
代表了参与投票的人喜爱的3项运动。

输出 :按字母序的先后顺序输出一行最受欢迎的前三项运动, 每两项之间由一个空格隔开。

sample input:
3
tennis basketball golf
tennis football basketball
badminton tennis chess

sample output:
badminton basketball tennis

代码如下:
#pragma warning(disable:4786)
#include<iostream>
#include<algorithm>
#include<map>
#include<string>
using namespace std;

bool cmp(const string a,const string b)
{
	return a < b;
}

int main()
{
	map<string,int> mmap;
	map<string,int>::iterator iter;
	int m,i;
	cin>>m;
	string str[3];
	while(m--)
	{
		cin>>str[0]>>str[1]>>str[2];
		for(i=0;i<3;i++)
		{
			iter = mmap.find(str[i]);
			if(iter == mmap.end())//查找不到
				mmap[str[i]] = 1;
			else
				mmap[str[i]]++;
		}
	}
	int value[3];
	for(i=0;i<3;i++)
	{
		iter = mmap.begin();
		str[i] = iter->first;
		value[i] = iter->second;//保存最大值,其实题目并没有要求记录这个
		iter++;
		for(;iter!=mmap.end();iter++)
		{		
			if(iter->second > value[i])//后者值大的话
			{
				str[i] = iter->first;
				value[i] = iter->second;
			}
			else if(iter->second == value[i])//两者值相等的话
			{
				if(iter->first < str[i])//比较字典序
				{
					str[i] = iter->first;
					value[i] = iter->second;
				}
			}
		}
		mmap.erase(str[i]);//删除已经找到的最大元素
	}
	sort(str,str+3,cmp);//按字典需排列
	cout<<str[0]<<" "<<str[1]<<" "<<str[2]<<endl;
	return 0;
}
是不是发现有了map解决这类问题简单了很多。

例题二

题目描述:
    哈利波特在魔法学校的必修课之一就是学习魔咒。据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助。

    给你一部魔咒词典。当哈利听到一个魔咒时,你的程序必须告诉他那个魔咒的功能;当哈利需要某个功能但不知道该用什么魔咒时,你的程序要替他找到相应的魔咒。如果他要的魔咒不在词典中,就输出“what?”
输入:
    首先列出词典中不超过100000条不同的魔咒词条,每条格式为:

    [魔咒] 对应功能

    其中“魔咒”和“对应功能”分别为长度不超过20和80的字符串,字符串中保证不包含字符“[”和“]”,且“]”和后面的字符串之间有且仅有一个空格。词典最后一行以“@END@”结束,这一行不属于词典中的词条。
    词典之后的一行包含正整数N(<=1000),随后是N个测试用例。每个测试用例占一行,或者给出“[魔咒]”,或者给出“对应功能”。
输出:
    每个测试用例的输出占一行,输出魔咒对应的功能,或者功能对应的魔咒。如果魔咒不在词典中,就输出“what?”
sample input:
[expelliarmus] the disarming charm
[rictusempra] send a jet of silver light to hit the enemy
[tarantallegra] control the movement of one's legs
[serpensortia] shoot a snake out of the end of one's wand
[lumos] light the wand
[obliviate] the memory charm
[expecto patronum] send a Patronus to the dementors
[accio] the summoning charm
@END@
4
[lumos]
the summoning charm
[arha]
take me to the sky
sample output:
light the wand
accio
what?
what?
#pragma warning(disable:4786)
#include<iostream>
#include<map>
#include<string>
using namespace std;

int main()
{
	char cstr[100];
	map<string,string> mmap1;//记录魔咒-解释
	map<string,string> mmap2;//记录解释-魔咒
	map<string,string>::iterator iter;//迭代器
	while(gets(cstr))
	{
		string sstr(cstr);
		if(sstr == "@END@")
			break;
		int index = sstr.find(']');
		string sstr1 = sstr.substr(0,index+1);//先记录[和]
		string sstr2 = sstr.substr(index+2);//除去空格
		//cout<<sstr1<<":"<<sstr2<<endl;
		mmap1[sstr1] = sstr2;
		mmap2[sstr2] = sstr1.substr(1,sstr1.length()-2);//解释-魔咒中魔咒不含[和]		
	}
	int n;
	cin>>n;
	gets(cstr);//在cin后面跟着gets的话gets会把cin的\n识别为字符串,所以进入循环之前先输入一次(环境vc6)
	while(n--)
	{
		gets(cstr);
		string str(cstr);
		if(str[0] == '[')//说明是魔法要查定义
		{
			iter = mmap1.find(str);
			if(iter != mmap1.end())//如果找到
				cout<<mmap1[str]<<endl;
			else
				cout<<"what?"<<endl;
		}
		else//说明是定义要查魔法
		{
			iter = mmap2.find(str);
			if(iter != mmap2.end())
				cout<<mmap2[str]<<endl;
			else
				cout<<"what?"<<endl;
		}
	}
	return 0;
}
这里之所以没有使用getline直接读入string,是因为在我的编译环境中(vc6)发现使用getline需要两次回车才能读入一个字符串。在高版本的vs中没有这个问题。



猜你喜欢

转载自blog.csdn.net/cassiepython/article/details/61614410