map | 关联数组:元素通过键来存储和读取 |
set | 大小可变的集合,支持通过键实现的快速读取 |
multimap | 支持同一个键多次出现的map类型 |
multiset | 支持同一个键多次出现的set类型 |
pair<T1, T2> p1; | 创建一个空的pair对象,它的两个元素分别是T1和T2类型,采用值初始化 |
pair<T1, T2> p1(v1, v2); | 创建一个pair对象,它的两个元素分别是T1和T2类型,其中first成员初始化为v1,second成员初始化为v2 |
make_pair(v1, v2) | 以v1和v2值创建一个新的pair对象,其元素类型分别是v1和v2的类型 |
p1 < p2 | 字典次序:如果p1.first<p2.first或者!(p2.first < p1.first)&& p1.second<p2.second,则返回true |
p1 == p2 | 如果两个pair对象的first和second成员依次相等,则这两个对象相等。 |
p.first | 返回p中名为first的(公有)数据成员 |
p.second | 返回p中名为second的(公有)数据成员 |
map类型
map<K, V>::key_type | 在map容器内,用做索引的键的类型 |
map<K, V>::mapped_type | 在map容器中,键所关联的值的类型 |
map<K, V>::value_type | map的值类型:一个pair类型,它的first元素具有 const map<K, V>::key_type类型,而second元素 则为map<K, V>::mapped_type类型 |
map<K, V> m; | 创建一个名为m的空map对象,其键和值的类型分别为K和V |
map<K, V> m(m2); | 创建m2的副本m,m与m2必须有相同的键类型和值类型 |
map<k, V> m(b, e); | 创建map类型的对象m,存储迭代器b和e标记的范围内所有元素的副本。元素的类型必须能转换为pair<const k, v> |
A::reference operator[](const Key& key); |
[]操作符返回键key所关联的值的引用;如果该键key不存在,则向map对象添加一个新的元素,元素的键为key,所关联的值采用值初始化。(要特别留意这个副作用) |
例如:
#include<iostream>
#include<map>
using namespace std;
int main()
{
map<char,int> mymap;
map<char,int>::iterator it;
pair<map<char,int>::iterator,bool> ret1;
pair<map<char,int>::iterator,map<char,int>::iterator> ret;
//插入元素
mymap['a']=10;
mymap['b']=20;
mymap['c']=30;
mymap['d']=40;
ret1=mymap.insert(pair<char,int>('c',500));
if (ret1.second==false)
{
cout << "element 'c' already existed";
cout << " with a value of " << ret1.first->second << endl;
}
//寻找、删除
it=mymap.find('d');
mymap.erase (it);
//边界
ret = mymap.equal_range('b');
cout << "lower bound points to: ";
cout << ret.first->first << " => " << ret.first->second << endl;
cout << "upper bound points to: ";
cout << ret.second->first << " => " << ret.second->second << endl;
// 输出容器元素
cout << "mymap contains:\n";
for ( it=mymap.begin() ; it != mymap.end(); it++ )
cout << (*it).first << " => " << (*it).second << endl;
return 0;
}
m.insert(e) | e是一个用在m上的value_type类型的值,如果键(e.first)不在m中,则插入e到m中;如果键已经在m中存在,则保持m不变。 该函数返回一个pair类型对象,如果发生了插入动作,则返回pair(it, true);否则返回pair(it, false)。其中,it是指向键为e.first那个元素的迭代器。 |
m.insert(beg, end) | beg和end是标记元素范围的迭代器,其中的元素必须为value_type类型的键-值对。对于该范围内的所有元素,如果它的键在m中不存在,则将该键及其关联的值插入到m。返回void类型。 |
m.insert(iter, e) | insert(e),并以iter为起点搜索新元素的位置。返回一个迭代器,指向m中键为e.first的元素。 |
m.count(k) | 返回m中k的出现次数(0或1) |
m.find(k) | 如果容器中存在键为k的元素,则返回指向该元素的迭代器。 如果不存在,则返回end()值。 |
m.erase(k) | 删除m中键为k的元素,返回size_type类型的值,表示删除的元素个数(0或1) |
m.erase(p) | 从m中删除迭代器p所指向的元素。p必须指向m中确实存在的元素,而且不能等于e.end()。返回void类型 |
m.erase(b, e) | 从m中删除[b, e)范围内的元素,返回void类型 |
set类型
multimap和multiset类型
m.lower_bound(k) | 返回一个迭代器,指向键不小于k的第一个元素 |
m.upper_bound(k) | 返回一个迭代器,指向键大于k的第一个元素 |
m.equal_range(k) | 返回一个迭代器的pair对象;它的first成员等价于 m.lower_bound(k),而second成员则等价于 m.upper_bound(k) |
lower_bound()是binary_search()的特殊形式. 此函数搜索给定的序列[first, end)中val可插入的第一个位置; 或者说, 它返回序列中遇到的第一个不小于val的元素的迭代器, 如果所有元素都小于val则返回“end”. 从函数要求待搜索序列是有序的.
lower_bound()的返回值乃是一个指向val可以安全插入的位置的迭代器. 在比较函数f被指定之前, 默认使用<操作符进行排序.
例如, 下面的代码借助lower_bound()将7插入到一个已排序好的vector中:
#include<iostream>
#include <algorithm>
#include<vector>
using namespace std;
int main()
{
vector<int> nums;
nums.push_back(-242);
nums.push_back(-1);
nums.push_back(0);
nums.push_back(5);
nums.push_back(8);
nums.push_back(8);
nums.push_back(11);
cout<<"Before nums is: ";
for(unsigned int i=0;i<nums.size();i++)
cout<<nums[i]<<" ";
cout<<endl;
vector<int>::iterator result;
int new_val=7;
result=lower_bound(nums.begin(),nums.end(),new_val);
nums.insert(result,new_val);
cout << "After, nums is: ";
for(i = 0; i < nums.size(); i++ )
cout << nums[i] << " ";
cout << endl;
return 0;
}
输出结果为:
Before nums is: -242 -1 0 5 8 8 11
After, nums is: -242 -1 0 5 7 8 8 11
Press any key to continue
upper_bound用法和lower_bound相似。
在没有map和set时候要用到这三个函数要声明算法的头文件
函数equal_range()返回first和last之间等于val的元素区间. 此函数假定first和last区间内的元素可以使用<操作符或者指定的comp执行比较操作.
equal_range()可以被认为是lower_bound和upper_bound的结合, pair中的第一个迭代器由lower_bound返回, 第二个则由upper_bound返回.
例如, 下面的代码使用equal_range()探测一个有序的vector中的可以插入数字8的位置:
#include<iostream>
#include <algorithm>
#include<vector>
using namespace std;
int main()
{
vector<int> nums;
nums.push_back( -242 );
nums.push_back( -1 );
nums.push_back( 0 );
nums.push_back( 5 );
nums.push_back( 8 );
nums.push_back( 8 );
nums.push_back( 11 );
pair<vector<int>::iterator, vector<int>::iterator> result;
int new_val = 8;
result = equal_range( nums.begin(), nums.end(), new_val);
cout<< "The first place that " << new_val
<< " could be inserted is before " << *result.first
<< ", and the last place that it could be inserted is before " << *result.second
<< endl;
return 0;
}
输出结果为:
The first place that 8 could be inserted is before 8, and the last place that it
could be inserted is before 11
下面是一个map例子
#pragma warning (disable : 4786)
#include<iostream>
#include<cstdio>
#include<string>
#include<map>
using namespace std;
const int N = 100;
struct student{
string name;
int id;
string blog;
}s[N];
int main()
{
int i,n;
map<string,int>m;//用 name 和 结构体数组下标 建立映射
m.clear();//清空map,判空用empty()
//freopen("data.in","r",stdin);
//freopen("my.out","w",stdout);
scanf("%d",&n);
for(i=1;i<=n;i++){
cin>>s[i].name>>s[i].id>>s[i].blog;
/*************第一种插入方式************/
m.insert(pair<string,int>(s[i].name,i));
/*************第二种插入方式************/
//m.insert(map<string,int>::value_type(s[i].name,i));
/*************第三种插入方式************/
//m[s[i].name]=i;
}
/*********** map的大小 ************/
cout<<"元素个数"<<":"<<" "<<m.size()<<endl;
cout<<endl;
/************遍历操作1: 前向迭代器*************
map<string,int>::iterator p;
for(p=m.begin();p!=m.end();p++){
int k=p->second;
cout<<p->first<<" "<<s[k].id<<" "<<s[k].blog<<endl;
}
*/
/************遍历操作2: 反向迭代器*************
map<string,int>::reverse_iterator p;
for(p=m.rbegin();p!=m.rend();p++){
int k=p->second;
cout<<p->first<<" "<<s[k].id<<" "<<s[k].blog<<endl;
}
**********************************************/
/************遍历操作3: 数组遍历*************/
for(int pi=1;pi<=m.size();pi++){
cout<<s[pi].name<<" "<<s[pi].id<<" "<<s[pi].blog<<endl;
}
/************************查找*******************************/
/********** m.count() **********/
if(!m.count("Lch"))cout<<"No answer!"<<endl;
else cout<<"Yes,you got it!"<<endl;
/******* m.find()函数 ********
map<string,int>::iterator p;
p=m.find("Lch");
if(p!=m.end()){
int k=p->second;
cout<<p->first<<" "<<s[k].id<<" "<<s[k].blog<<endl;
}
else cout<<"No answer!!!!"<<endl;
*******************************/
/*** m.lower_bound 和 m.upper_bound ***/
map<string,int>::iterator p1,p2;
p2=m.lower_bound("Lch");
p1=m.upper_bound("Lch");
if(p1==p2)cout<<"No answer!"<<endl;
else cout<<"Yes,you got it!"<<endl;
/*********************** 删除 *******************************/
/************* erase() **************/
//按关键字删除
//int x=m.erase("Lch");
//cout<<x<<endl;
//迭代器删除
map<string,int>::iterator p;
p=m.find("Lch");
m.erase(p);
//区间删除
m.erase(m.begin(),m.end());
if(!m.count("Lch"))cout<<"No answer!"<<endl;
else cout<<"Yes,you got it!"<<endl;
return 0;
}
以上资料整理于网络