C++ map使用详解

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();    //返回指向起始元素的前一个的迭代器

Map迭代器

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. 自定义的类做mapkey

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 << ' ';
}

参考网站

cppreference.com

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中的map是一个键值对的集合容器,可以用来存储一些相关数据。它的定义类似于一个结构体,使用时要先定义一个map类型的变量,然后再添加键值对。 定义map类型变量的方式为: ``` map<key_type, value_type> my_map; ``` 其中,key_type和value_type分别是键和值的类型,可以是任意类型的数据。在使用map之前,需要先包含头文件<map.h>。 接下来,可以通过以下代码向map中添加键值对: ``` my_map[key] = value; ``` 其中,key为要添加的键,value为要添加的值。如果键已经存在,则会更新该键的值。 可以通过以下方式访问map中的值: ``` my_map[key] ``` 这里的key为所要访问的键。如果该键存在,则返回其对应的值,否则返回默认值(通常为0或空)。 还可以使用以下代码来遍历所有的键值对: ``` for (auto it = my_map.begin(); it != my_map.end(); ++it) { auto key = it->first; auto value = it->second; // TODO:对键值对进行操作 } ``` 其中,auto关键字可以自动推断变量类型,it->first用于获当前键值对的键,it->second用于获当前键值对的值。 除了上述常用的操作,还有一些其他的操作,如: - erase(key):用于删除指定键的键值对; - count(key):返回指定键出现的次数(通常是0或1); - empty():判断map是否为空; - size():返回map中键值对的数目。 总的来说,C语言中map使用十分灵活,能够方便地存储和操作多个键值对。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值