1. 程式人生 > >C++ map使用詳解

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

參考網站

相關推薦

C++ map

1、map 物件的定義 map<k, v> m; 建立一個名為m的空map物件,其鍵和值得型別分別為k和v map<k, v> m(m1); 建立m1的副本m,m與m1必須有相同的鍵型別和值型別 ma

C++ STL map

索引 turn clas c++ ltr 能力 code 宋體 快速 一.解釋: p { margin-bottom: 0.25cm; direction: ltr; color: #00000a; line-height: 120%; text-align: justif

C# LINQ From Where Select Group Into OrderBy Let Join

分享 str 關聯 例如 數據 lln ole inf emp 目錄 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小結 1. 概述

C++ 模板(二)(轉)

創建 規則 error ++ 例如 public err iostream () 四、類模板的默認模板類型形參   1、可以為類模板的類型形參提供默認值,但不能為函數模板的類型形參提供默認值。函數模板和類模板都可以為模板的非類型形參提供默認值。   2、類模板的類型形

C-pthread_cond_wait

read thread 一個 同時 多個 wait 產生 adc 全部 pthread_cond_wait() 用於阻塞當前線程,等待別的線程使用 pthread_cond_signal() 或 pthread_cond_broadcast 來喚醒它。 pthread_co

[js高手之路] es6系列教程 - Map以及常用api

.com size style 系列教程 image clear rsquo images div ECMAScript 6中的Map類型是一種存儲著許多鍵值對的有序列表。鍵值對支持所有的數據類型. 鍵 0 和 ‘0’會被當做兩個不同的鍵,不會發生強

Java中List,Set和Map及其區別

內部 特殊 set contain 快速查找 簡單 rar dset 維護 Java中的集合包括三大類,它們是Set(集)、List(列表)和Map(映射),它們都處於java.util包中,Set、List和Map都是接口,它們有各自的實現類。Set的實現類主要有Hash

C#】屬性

radi 們的 cal com 位數 struct serializa 表達式 font 目錄結構: contents structure [+] 屬性和字段的區別 無參屬性 自動實現的屬性 對象和集合初始化器 匿名類型 System.Tu

C# DataTable

lec row 條件 而且 獲取 int mar 索引 typeof 添加引用 using System.Data; 創建表 //創建一個空表 DataTable dt = new DataTable(); //創建一個名為"Table_New"的空表 DataT

廣義表C/C++實現

所謂的廣義表就是單鏈表的擴充套件,就是節點可以是一個元素也可以是一個連結串列。官方的說法是,原子節點和子表節點。廣義表用遞迴的方法來建立是最簡單易懂的,也符合廣義表的思想。 C程式碼實現下載 C++程式碼實現下載 (備用下載地址 ) 1.廣義表的各種形態 (1)、A = (

C++ 類

1、類的定義 class 類名稱 { public:      公有成員(外部介面,可被使用該類的所有程式碼所使用) private:      私有成員 (只允許本類中的函式訪問,而類外部的任何

C#反射

ron new t getc 給定 types console const property rom http://blog.csdn.net/educast/article/details/2894892(轉) 兩個現實中的例子:1、B超:大家體檢的時候大概都做過B超吧,

C# 特性(Attribute)

今天整理關於特性的資料,之前都忘了,今天整理一下 參考《C#高階程式設計》第10版 0X01 特性(Attribute) 特性定義 特性不會影響編譯過程,因為編譯器不能識別它們,但這些特性在應用於程式元素

C++容器

什麼是容器 首先,我們必須理解一下什麼是容器,在C++ 中容器被定義為:在資料儲存上,有一種物件型別,它可以持有其它物件或指向其它對像的指標,這種物件型別就叫做容器。很簡單,容器就是儲存其它物件的對 象,當然這是一個樸素的理解,這種“物件”還包含了一系列處理“其它物件”的方法,因為這些方法在程式

C/C++陣列(一維和二維)

陣列這東西,說說都懂,但是似乎並沒有完全吃透,導致很多地方有疑惑。所以再梳理一遍。   陣列定義 陣列是存放型別相同的物件的容器,這些物件本身沒有名字,需要通過其所在位置訪問。 從定義中可以看出,陣列存放的是物件且型別相同。所以不存在引用的物件(引用不是物件)

哈夫曼樹C++實現

哈夫曼樹的介紹 Huffman Tree,中文名是哈夫曼樹或霍夫曼樹,它是最優二叉樹。 定義:給定n個權值作為n個葉子結點,構造一棵二叉樹,若樹的帶權路徑長度達到最小,則這棵樹被稱為哈夫曼樹。 這個定義裡面涉及到了幾個陌生的概念,下面就是一顆哈夫曼樹,我們來看圖解答。 (01) 路徑和路徑長度

c++ pair

總述: 介紹pair的基本用法,包括pair的建立,排序,使用特性等 1.pair的建立 a.pair<int,int> p或者pair<int,int>p(0,1). b.可以使用make_pair()函式建立一個臨時的pair變數,常用作pair作為函式引

C#Assembly

       Assembly, 這裡把它翻譯為配件或程式集, 以示和元件(Component)加以區別。一個配件有時候是指一個EXE或者DLL檔案, 實際上是一個應用程式(就是指帶有主程式入口點的模組)或者一個庫檔案。但是配件實際上可以是由一個或者多個檔案組

NOIP 2018普及組初賽C/C++答案

一、單項選擇題 1 D 印表機是把電腦裡的資料列印到紙上,所以是輸出裝置。 掃描器、鍵盤和滑鼠都是往電腦裡輸入東西,是輸入裝置。 2 D 二進位制化八進位制:從低位(右)往高位(左),每三位直接換成八進位制即可。 (1001101011)2 = (10 0110 1011)2 =

NOIP 2011初賽普及組C/C++答案

一、單項選擇題 1 B 1 1 0 0 1 1 0 - 1 0 1 1 0 0 1 ------------------------ = 0 0 0 1 1 0 1 2 B 48 + 9 = 57 3 C 8G = 8 * 1024 M 8 * 1024 /