C++ map
使用详解
简介
使用map
的时候发现很多细节部分还是不清楚,所以重新整理一下。
#include <map>
map
是使用红黑树实现的,访问、查找和删除操作的复杂度都是O(logn)
。
template<
class Key, //键
class T, //值
class Compare = std::less<Key>, //
class Allocator = std::allocator<std::pair<const Key, T> >
> class map;
注意: 默认的情况下,Key
要支持<
操作,并且排序规则是从小到大。
一. 构造函数
map
的构造函数方式大体来说有如下几种:
std::map<std::string, int> default_map; //默认构造
std::map<std::string, int> copied_map(default_map); //拷贝构造
std::map<std::string, int> iter_map(default_map.find("abc"), default_map.end()); //Range constructor
//C++11 初始值列构造
std::map<std::string, int> init_map {
{"this", 100},
{"can", 100},
{"be", 100},
{"const", 100},
};
二. 遍历操作
遍历map
无疑就需要使用到迭代器,下面列出了四种map
迭代器,详细的遍历可以看下文的代码部分。
iterator begin(); //返回指向起始元素的迭代器
iterator rbegin(); //返回指向末尾元素的迭代器
iterator end(); //返回指向末尾元素的后一个的迭代器
iterator rend(); //返回指向起始元素的前一个的迭代器
C++11
中还加入了at()
函数,这里就不做介绍了。
三. 插入操作
1. 使用[]
插入
直接使用[]
插入,如果mymap
中不存在键值为"abc"
元素,那么就执行插入操作。
- 操作示例:mymap["abc"] = 1;
2. 插入单个元素
- 函数原型:
std::pair<iterator,bool> insert( const value_type& value ); //这里的返回值:bool表示插入是否成功、iterator返回插入的位置
- 操作示例:
mymap.insert( std::map<int, std::string>::value_type(1, "one") );
3. 插入多个元素
//函数原型:
template< class InputIt >
void insert( InputIt first, InputIt last );
//操作示例:
std::map<int, std::string> tmp = {
{5, "five"},
{6, "six"}
};
mymap.insert( tmp.begin(),tmp.end() );
4. 使用std::initializer_list
插入
C++11
中新加入的插入数据方式:
- 函数原型:void insert( std::initializer_list<value_type> ilist );
- 操作示例:mymap.insert( { {7, "seven"}, {8, "eight"}, {9, "nine"} } );
四. 删除操作
1. 删除指定位置的元素
函数原型:iterator erase( iterator pos );
具体示例:std::map<std::string,int>::iterator it = mymap.erase(mymap.begin()); //返回删除元素的下一个元素的迭代器
2. 删除指定范围的元素
函数原型:iterator erase( const_iterator first, const_iterator last );
具体示例:mymap.erase(mymap.begin(), mymap.end()); //删除所有的元素
3. 依据键值删除元素
函数原型:size_type erase( const key_type& key );
具体示例:int num = mymap.erase("abc");
PS:方法一和方法二的返回值都是删除元素的下一个元素的迭代器,在C++11
之前他们都是没有返回值的。方法三的返回值是删除元素的数目。
五. 其他方法
size_type size() const; //返回map中元素的个数
bool empty() const; //判断map是否为空
void clear(); //移除所有元素
size_type max_size() const; //map中最多可以存储多少元素
void swap( map& other ); //交换数据
size_type count( const Key& key ) const; //返回关键字为key的元素的个数,在map里结果不是0就是1
iterator find( const Key& key ); //返回key所在位置的迭代器,如果没有找到则返回end()
六. 运算符操作
operator:
==
!=
<
<=
>
>=
注意==
与!=
运算符,完全相同才是相等的,包括顺序!
七. 使用
1. 自定义的类做map
的key
在map
中使用自定义的类关键是重载<
。
#include <iostream>
#include <string>
#include <map>
class LOG
{
public:
std::string msg;
int line;
public:
LOG(const std::string& s, const int& l)
{
msg = s;
line = l;
}
bool operator<(const LOG& e) const //排序规则,重载,
{
if (msg>e.msg)
{
return true;
}
else if (msg == e.msg)
{
return line > e.line;
}
else
return false;
}
};
const LOG data[] =
{
{"A", 1},
{"B", 2},
{"A", 1},
{"B", 3},
{"A", 2},
};
int main()
{
std::map<LOG, int> m;
for (auto e : data)
{
if (m.find(e) == m.end())//没有找到
m[e] = 1;
else
++m[e];
}
for (auto e : m)
{
std::cout << e.first.msg << " " << e.first.line << " " << e.second << std::endl;
}
system("pause");
return 0;
}
2. 自定义排序规则
仿照std::less<Key>
写自己的排序规则
#include <map>
#include <iostream>
template <typename T>
struct cmp {
bool operator() (const T& x, const T& y) const
{
return x>y; //这里的T支持 > 操作
}
};
struct cmp {
bool operator() (const int& x, const int& y) const
{
return x>y;
}
};
int main()
{
//如果使用模板类则需要写cmp<int> 如果是直接使用类就直接使用cmp
std::map<int, std::string, cmp > c = {
{1, "one"},
{2, "two"},
{3, "three"},
{4, "four"},
{5, "five"},
{6, "six"}
};
for(auto& p : c)
std::cout << p.second << ' ';
}