stl map与multimap的使用

map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。

multimap:允许关键值重复,重复的关键值可以有不同的val,map不允许关键值重复。

C++ map是一种关联式容器,包含“关键字/值”对

头文件
#include<map>

变量定义
map<int,int> m;

主要函数

begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
lower_bound() 返回键值>=给定元素的第一个位置
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
upper_bound() 返回键值>给定元素的第一个位置

实例一

#include<iostream>
#include<map>
using namespace std;
int main()
{
    map<int,string> map1;//定义
    map1[13]="beijing";//添加元素key:13,val:beijing 
    map1.insert(map<int,string>::value_type(2,"xian"));//添加元素key:2,val:xian
    map1.insert(pair<int,string>(1,"china")); 
    map1.insert(make_pair<int,string>(4,"V5"));
    map<int,string>::iterator it;
    //map自动按key的值进行排序 
    for (it=map1.begin();it!=map1.end();it++)
   {
        cout<<it->first<<":"<<it->second<<" ";
    }
    cout<<endl<<"-------"<<endl;
    map1[13]="this";//修改key为13val为this
    map1.insert(pair<int,string>(1,"China"));//不会修改key为1的val
    map1.insert(make_pair<int,string>(4,"V6")); //不会修改 
    map1.insert(map<int,string>::value_type(2,"Xian"));//不会修改 
    for (it=map1.begin();it!=map1.end();it++)
    {
         cout<<it->first<<":"<<it->second<<" ";//it->first获取key的值,it->second获取val的值 
    }
    cout<<endl<<"-------"<<endl;
    cout<<map1.find(1)->second<<endl;
    //cout<<map1.find(19)->second<<endl; 注意这里没有key为19的值,故运行时会出错
    //因此查找key的val值正确的做法应为
    it=map1.find(19);
    if(it==map1.end())
    {
        cout<<"No found"<<endl;//没有查找成功时	
    }
    else
    {
        cout<<it->second<<endl; 
    } 
    it=map1.find(1);
    if(it==map1.end())
    {
         cout<<"No found"<<endl;//没有查找成功时	
     }
    else
    {
         cout<<it->second<<endl; 
    } 
    it=map1.lower_bound(2);
    if (it!=map1.end())
    {
         cout<<it->first<<":"<<it->second<<endl;
    }
    it=map1.upper_bound(2);
    if (it!=map1.end())
    {
         cout<<it->first<<":"<<it->second<<endl;
    }
    map1.erase(2);
    for (it=map1.begin();it!=map1.end();it++)
    {
         cout<<it->first<<":"<<it->second<<" ";//it->first获取key的值,it->second获取val的值 
    }
    cout<<endl<<"-------"<<endl;
    map1.erase(8);
    for (it=map1.begin();it!=map1.end();it++)
    {
           cout<<it->first<<":"<<it->second<<" ";//it->first获取key的值,it->second获取val的值 
     }
     cout<<endl<<"-------"<<endl;
     return 0;
}

实例二

1)根据要删除的键值对位于容器中的位置,实现删除该键值对。
//删除map容器种指定位置的键值对
iterator erase(const_iterator position);
其中,position为迭代器,指向要删除的键值对。
该方法会返回一个iterator迭代器,其指向的是删除键值对之后的那个键值对(如果是删除最后一个键值对,那么该方法也会返回迭代器指向的最后一个键值对之后的位置)。

#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
    //创建并初始化map容器
    map<string,int> myMap{{"penny",1},{"leonard",2},{"sheldon",3},{"howard",4}};
    cout<<myMap.size()<<endl; //输出键值对个数
    //遍历map容器 
    for(auto iter = myMap.begin(); iter != myMap.end(); iter++){
    	cout<<iter->first<<","<<iter->second<<"  ";
	} 
	cout<<endl;
    //创建一个指向要删除键值对的迭代器
    map<string,int>::iterator iter = ++myMap.begin(); //指向第二个键值对
    //执行删除操作
    map<string,int>::iterator ret = myMap.erase(iter);
    cout<<myMap.size()<<endl; //输出键值对个数
    //输出erase()方法返回的迭代器指向的键值对
    cout<<ret->first<<" "<<ret->second<<endl;
    return 0;
}

实例三

2)传入要删除目标键值对的键的值,该方法会自行根据指定的键找到目标键值对,并将其删除。
//删除map容器种键为k的键值对
size_type erase(const key_type& k);
其中,参数k为要删除的键值对的键的值。
该方法的返回值为成功删除的键值对的个数。由于map容器种每个键值对的键都是独一无二的,故其返回值最大为1.

#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
    //创建并初始化map容器
    map<string,int> myMap{{"penny",1},{"leonard",2},{"sheldon",3},{"howard",4}};
    cout<<myMap.size()<<endl; //输出键值对个数
    //执行删除操作,删除myMap容器种键为"penny"的键值对
    int num = myMap.erase("penny");
    cout<<myMap.size()<<endl; //输出键值对个数
    //输出erase()方法的返回值
    cout<<"num= "<<num<<endl;
    return 0;
}

实例四

3)在某些情况下,可能需要删除某个指定区域内的所有键值对,也可以通过erase()方法实现。
//删除 map 容器中位于 [first,last) 区域内的所有键值对
iterator erase (const_iterator first, const_iterator last);
其中参数first和last都是迭代器,[first, last)就表示map容器种的某个范围,该方法会删除此范围内的所有键值对。
返回值为一个迭代器,其指向删除范围之后的第一个键值对。如果该范围之后,不再有任何键值对,则返回的迭代器指向map容器最后一个键值对之后的位置。

#include<iostream>
#include<map>
#include<string>
using namespace std;
int main(){
    //创建并初始化map容器
    map<string,int> myMap{{"penny",1},{"leonard",2},{"sheldon",3},{"howard",4}};
    cout<<myMap.size()<<endl; //输出键值对个数
    //指定范围
    map<string,int>::iterator first = myMap.begin();
    map<string,int>::iterator last = --myMap.end();
    //删除指定范围内的容器
    map<string,int>::iterator ret = myMap.erase(first,last);
    cout<<myMap.size()<<endl;
    cout<<ret->first<<" "<<ret->second<<endl;
    return 0;
}

实例五:
insert插入相同键值时不会改变原有的值

#include<bits/stdc++.h>
using namespace std;
map<int,int> ma;
int main()
{
	int n;
	cin>>n;
	for (int i=1;i<=n;i++)
	{
		int x,y;
		cin>>x>>y;
		ma.insert(pair<int,int> (x,y)); //插入相同键值的时候不会改变 
		map<int,int>::iterator it;
		for (it=ma.begin();it!=ma.end();it++)
		{
			cout<<(it->first)<<" "<<(it->second)<<endl;
		}
		cout<<"----"<<endl;
	}
}
/*
in
8
4 5
4 3
1 2
3 7
3 8
8 9
4 0
5 6
out
8
4 5
----
4 5
----
1 2
4 5
----
1 2
3 7
4 5
----
1 2
3 7
4 5
----
1 2
3 7
4 5
8 9
----
1 2
3 7
4 5
8 9
----
1 2
3 7
4 5
5 6
8 9
----
*/ 

使用数组形式可以改变原有的值

#include<bits/stdc++.h>
using namespace std;
map<int,int> ma;
int main()
{
	int n;
	cin>>n;
	for (int i=1;i<=n;i++)
	{
		int x,y;
		cin>>x>>y;
		ma[x]=y; //数组方式可以修改原有的值 
		map<int,int>::iterator it;
		for (it=ma.begin();it!=ma.end();it++)
		{
			cout<<(it->first)<<" "<<(it->second)<<endl;
		}
		cout<<"----"<<endl;
	}
}
/*
in
8
4 5
4 3
1 2
3 7
3 8
8 9
4 0
5 6
out
4 5
----
4 3
----
1 2
4 3
----
1 2
3 7
4 3
----
1 2
3 8
4 3
----
1 2
3 8
4 3
8 9
----
1 2
3 8
4 0
8 9
----
1 2
3 8
4 0
5 6
8 9
----
*/ 

multimap不支特数组的插入形式
map使用结构体的实例

//当元素为结构体时自定义排序 
#include <iostream>  
#include <map>     
#include <utility> 
using namespace std; 
struct Info 
{ 
 	string name; 
 	float score; 
 	//重载"<"操作符,自定义排序规则 
 	bool operator < (const Info &a) const 
 	{ 
 		if(score==a.score)
 			return name>a.name;
 		return score>a.score; 
 	} 
}; 
int main() 
{ 
 
 	map<Info,int> m; 
 	Info info; 
 	info.name="Jack"; 
 	info.score=60; 
 	m[info]=25; 
 	info.name="Tom";
 	info.score=60;
 	m[info]=30;
 	info.name="Bomi"; 
 	info.score=80; 
 	m[info]=10; 
 	info.name="Peti"; 
 	info.score=66.5; 
 	m[info]=30;  
 	map<Info,int>::iterator it; 
 	for(it=m.begin();it!=m.end();it++) 
 	{ 
 		cout<<(*it).second<<" : "; 
 		cout<<((*it).first).name<<" "<<((*it).first).score<<endl; 
 	} 
 	return 0; 
} 

  

 

posted @ 2022-02-28 21:31  心悟&&星际  阅读(165)  评论(0)    收藏  举报