STL——map(multimap)容器练习

1.

一个名为 "Berlanddesk" 的电子邮件系统即将在 Berland 上线运营。该电子邮件系统的管理员希望整个系统的建设可以尽早完成,因此他们找到了资深程序员您,希望您能够为他们开发一个用户注册系统的原型产品。

该系统的运行遵循以下原则:

新用户注册时,他将向系统发送一则内容为其用户名的请求,如果该用户名尚未存在于系统数据库内,则将该用户名插入数据库,同时用户得到回应信息 OK 表示其已经成功注册。如果用户请求的用户名已经存在于数据库内,那么系统将产生一个新的用户名并将其加入数据库。新用户名由用户请求的用户名与正整数 i 构成,i 为使 "用户名i" 尚未存在于数据库内的最小的 i。

输入格式

第一行一个整数 (1≤n≤105)n。接下来 n 行,每行表示用户向系统发出的一则请求。每行内容均非空且均为由至多 32个小写拉丁字母组成的字符串。

输出格式

n 行,每行表示系统对一则请求做出的回应。如果该用户名尚未存在于系统数据库内,则输出 OK 。如果用户请求的用户名已经被注册,则输出依照规则生成的新用户名。

示例:

4                          
abacaba                OK
acaba                  OK
abacaba                abacaba1
acab                   acab

代码1:

#include<iostream>
using namespace std;
#include<map>
#include<string>
int co[10005];
int main()
{
    int n;
    cin>>n;
    map<string,int>m;
    for(int i=1;i<=n;i++)
    {
        string s;
        cin>>s;
        if(m.find(s)==m.end())
        {
            cout<<"OK"<<endl;
            m.insert(make_pair(s,i));
        }
        else
        {
            int t=m.find(s)->second;
            cout<<s<<++co[t]<<endl;
        }
    }
}

代码2:

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
map<string,int>m;
int co[100005];
int main()//
{
    int n;
    string str;
    cin>>n;
    map<string,int>::iterator it;
    for(int i=1;i<=n;i++)
    {
        cin>>str;
        it=m.find(str);//找键为str的
        if(it==m.end())//没找到
        {
            m[str]=1;//存储该字符串出现的次数
            cout<<"OK"<<endl;
        }
        else//如果找到了
        {
            cout<<str<<m[str]++<<endl;//输出键——字符串和值——字符串出现次数并且次数+1
        }
    }
    return 0;
}

总结:1.map的两大核心功能,一是查找,二是键值关系。结合二者可以轻松实现桶排序且快速查找!

2.QQ账号

实现QQ新帐户申请和老帐户登陆的简化版功能。最大挑战是:据说现在的QQ号码已经有10位数了。

输入格式:
输入首先给出一个正整数N(≤105),随后给出N行指令。每行指令的格式为:“命令符(空格)QQ号码(空格)密码”。其中命令符为“N”(代表New)时表示要新申请一个QQ号,后面是新帐户的号码和密码;命令符为“L”(代表Login)时表示是老帐户登陆,后面是登陆信息。QQ号码为一个不超过10位、但大于1000(据说QQ老总的号码是1001)的整数。密码为不小于6位、不超过16位、且不包含空格的字符串。

输出格式:
针对每条指令,给出相应的信息:

1)若新申请帐户成功,则输出“New: OK”;
2)若新申请的号码已经存在,则输出“ERROR: Exist”;
3)若老帐户登陆成功,则输出“Login: OK”;
4)若老帐户QQ号码不存在,则输出“ERROR: Not Exist”;
5)若老帐户密码错误,则输出“ERROR: Wrong PW”。

自己写的代码:

#include<iostream>
using namespace std;
#include<map>
#include<string>
int main()
{
	int n;
	cin >> n;
	map<string, string>m;
	char a;
	while (n--)
	{
		string s1, s2;
		cin >> a >> s1 >> s2;
		map<string, string>::iterator it = m.find(s1);
		if (a == 'L')
		{
			if (it == m.end())
			{
				cout << "ERROR: Not Exist" << endl;
			}
			else
			{
				if (s2 == it->second)
				{
					cout << "Login: OK" << endl;
				}
				else
				{
					cout << "ERROR: Wrong Pw" << endl;
				}
			}

		}
		else
		{
			if (it == m.end())
			{
				cout << "New: OK"<< endl;
				m[s1] = s2;
			}
			else
			{
				cout << "ERROR: Exist" << endl;
			}
		}
	}
	return 0;
}

总结:账号密码一一对应,用map,干就对了!

3.寄包柜

超市里有 n(n≤10^5)个寄包柜。每个寄包柜格子数量不一,第 i 个寄包柜有 ai(ai≤10^5)个格子,不过我们并不知道各个 ai 的值。对于每个寄包柜,格子编号从 1 开始,一直到 ai。现在有 q(q≤10^5) 次操作:

1. i j k:在第 i个柜子的第 j 个格子存入物品 k(0≤k≤10^9)。当 k=0时说明清空该格子。
2.
i j:查询第 i 个柜子的第 j个格子中的物品是什么,保证查询的柜子有存过东西。
已知超市里共计不会超过 10^7个寄包格子,ai 是确定然而未知的,但是保证一定不小于该柜子存物品请求的格子编号的最大值。当然也有可能某些寄包柜中一个格子都没有。

自己写的代码:

#include<iostream>
using namespace std;
#include<map>
#include<string>
typedef long long ll;
class gui
{
public:
	ll first;
	ll second;
	bool operator<(const gui&a )const
	{
		return first < a.first;
	}
};
int main()
{
	map<gui, ll>m;
	int n, q;
	cin >> n >> q;
	for (int i = 0; i < q; i++)
	{
		int a;
		gui g;
		cin >> a >> g.first >> g.second;
		if (a == 1)
		{
			ll b;
			cin >> b;
			m[g] = b;
		}
		else
		{
			cout << m.find(g)->second << endl;
		}
	}
	return 0;
}

正确代码:

#include <bits/stdc++.h>
#include <cstdio>
using namespace std;
map<int,int> m[100005];
int main()
{
	int n, q, c, a, b, num;
	cin >> n >> q;
	while ( q-- ) {
		cin >> c >> a >> b;
		if ( c == 1 )
		{
			cin >> num;
			m[a][b] = num;
		}
		else {
			cout << m[a][b] << '\n';
		}
	}
	return 0;
}

总结:代码一:使用结构体作为map的键,关键是要对结构体的operator<运算符进行重载,必须要让两个结构体可比较大小,也就能让map按照键值自动排序,否则编译报错。

           代码二:二维map数组,思路就是利用map的快速查找,每个map组多占了一个int空间,位置标记十分明晰。 

4.MD6算法

MD5是一种信息摘要算法,它可以对任意大小的文件产生等长的密钥,当你在A主机使用MD5得到文件X的密钥后,在B主机同样对文件X使用MD5所得到密钥一定与A主机所得到的密钥相同。然后请实现MD5算法。
是的,我在开玩笑。
恩,我实现了一个MD6算法,它可以实现类似的功能。


本题包含多组样例。
输入第一行为数字N和Q,N为映射的行数,Q为询问的行数。
映射中每行包含一个字符串A(0<alen<30),和字符串A使用MD6算法对应的数字。
询问每行包含一个字符串A。

输出每个询问行中每个字符串使用MD6算法对应的数字。

示例:

输入:

5 3            
fs3fwe 3
4838fdeewerwer 54
irjfhid 888
847hhhh 1
0000 0
0000
847hhhh
fs3fwe

输出:

0

1

3

自己写的代码:

#include<map>
#include<string>
#include<iostream>
using namespace std;
int main()
{
	map<string, int>m;
	int n, q;
	cin >> n >> q;
	for (int i = 0; i < n; i++)
	{
		string s;
		int num;
		cin >> s>>num;
		m[s] = num;
	}
	for (int i = 0; i < q; i++)
	{
		string s;
		cin >> s;
		map<string,int>::iterator it=m.find(s);
		cout << it->second << endl;
	}
	return 0;
}

总结:题目中出现了极其明显的对应关系,用map,干就对了!

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ STL中的mapmultimap是关联容器,用于存储键值对(key-value pairs),其中每个键(key)唯一对应一个值(value)。 map是一个有序容器,根据键的大小进行自动排序,默认按照键的升序进行排序。每个键只能在map中出现一次,如果尝试插入具有相同键的元素,新元素将替代旧元素。 multimap也是一个有序容器,与map不同的是,它允许多个具有相同键的元素存在。多个具有相同键的元素将按照插入的顺序进行存储,而不会自动排序。 这两个容器都提供了一系列的操作函数,如insert、erase、find等,用于插入、删除和查找元素。 以下是一个使用map的简单示例: ```cpp #include <iostream> #include <map> int main() { std::map<std::string, int> scores; scores.insert(std::make_pair("Alice", 90)); scores.insert(std::make_pair("Bob", 80)); scores.insert(std::make_pair("Charlie", 70)); // 查找并输出Bob的分数 std::cout << "Bob's score: " << scores["Bob"] << std::endl; // 遍历并输出所有键值对 for (const auto& pair : scores) { std::cout << pair.first << ": " << pair.second << std::endl; } return 0; } ``` 上述示例中,我们创建了一个存储string类型键和int类型值的map容器scores。通过insert函数依次插入了三个键值对。然后我们通过scores["Bob"]来获取Bob的分数,并输出结果为80。 接着我们使用范围-based for循环遍历map中的所有键值对,并输出每个键值对的键和值。 multimap的用法与map类似,只是它允许多个具有相同键的元素存在。 这些关联容器在查找和插入操作上具有较高的效率,特别适用于需要根据键进行快速查找的场景。在实际应用中,你可以根据自己的需求选择适合的容器类型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值