STL標准庫-容器-map和multimap


技術在於交流、溝通,本文為博主原創文章轉載請注明出處並保持作品的完整性

map與multimap為關聯容器,結構如下

map底層實現依然是rb_tree 他的data可以改,但是key不能改,因此map仍然具有自動排序的功能

我們無法使用迭代器改變元素的key(const key),但是可以改變元素的data.

map的key必須獨一無二,multimap的key可以重復

map的定義函數

  template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
            typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
    class map
    {
    public:
      typedef _Key                                          key_type;
      typedef _Tp                                           mapped_type;
      typedef std::pair<const _Key, _Tp>                    value_type;
      typedef _Compare                                      key_compare;
      typedef _Alloc                                        allocator_type;
      ...
}

參數1 class key 鍵值key

參數2 class T data

參數3 class compare 排序key的函數 默認為less() 升序

參數4 alloc 分配器

 


 

 

map的基本使用

一 定義

    //構造函數
    map<int, int> c;
    c[1] = 10;
    c[2] = 20;
    c[3] = 30;
    c[4] = 40;
    c[5] = 50;
    for(auto i : c)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    
    //operator =
    map<int, int> c1;
    c1 = c;
    for(auto i : c)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;

 


 

二 迭代器操作 map的迭代器就是紅黑樹的迭代器

    //迭代器操作
    /*
    map<int, int> c;
    c.insert({pair<int, int>(1,10),pair<int, int>(2,20),pair<int, int>(3,30),pair<int, int>(4,40),pair<int, int>(5,50),pair<int, int>(6,60)});
    */

    //begin()
    map<int, int>::iterator iter;
    iter = c.begin();
    cout<< "begin(): "<<"["<< iter->first <<"] = " << iter->second <<endl;
    
    //end()
    iter = c.end();
    iter--;
    cout<<"end(): " <<"["<< iter->first <<"] = " << iter->second <<endl;
    
    //rbegin()反向頭迭代器
    map<int, int>::reverse_iterator riter;
    riter = c.rbegin();
    cout << "rbegin(): "<<"["<< riter->first <<"] = " << riter->second <<endl;
    
    //rend()反向頭迭代器
    riter = c.rend();
    riter--;
    cout << "rend(): "<<"["<< riter->first <<"] = " << riter->second <<endl;
    
    //cbegin() const 迭代器 正向 頭迭代器
    map<int, int>::const_iterator citer;
    citer = c.cbegin();
    cout << "cbegin(): "<<"["<< citer->first <<"] = " << citer->second <<endl;
    
    //cend() const 迭代器 反向 尾迭代器
    citer = c.cend();
    citer--;
    cout<< "cend(): "<<"["<< citer->first <<"] = " << citer->second <<endl;

 

 

 


 

三 容量

    //容量
    /*
     map<int, int> c;
     c.insert({pair<int, int>(1,10),pair<int, int>(2,20),pair<int, int>(3,30),pair<int, int>(4,40),pair<int, int>(5,50),pair<int, int>(6,60)});
     */
    //是否為kong
    cout << "empty: " << c.empty() <<endl;
    
    //元素個數
    cout << "size: " << c.size() <<endl;
    
    //最大容量
    cout << "max_size: " << c.max_size() <<endl;

 


 

四 基本操作

//基本操作
    /*
     map<int, int> c;
     c.insert({pair<int, int>(1,10),pair<int, int>(2,20),pair<int, int>(3,30),pair<int, int>(4,40),pair<int, int>(5,50),pair<int, int>(6,60)});
     */
    
    //operator[] 這個和其他容器的operator有些不同,如果[index] 的index(key) 在map中存在則直接返回該key對應的data ,如果不存在則想該位置插入默認值
    cout << "operator[]: " << c[1] << endl;
    cout << "operator[]: " << c[10] << endl; //這時你會發現 map自動插入一個c[10]
    for(auto i : c)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    
    //at() 取data
    cout<< "at(): " << c.at(3) << endl;
    
    //插入insert() map 不允許key重復 插入重復key 不會報錯但插入不成功
    c.insert(pair<int, int>(6, 15));
    cout <<"insetr(): ";
    for(auto i : c)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    

    map<int, int> c_insert;
    map<int, int>::iterator insert_iter = c_insert.begin();
    c_insert.insert(insert_iter,pair<int, int>(100, 10000));
    cout <<"insetr(): ";
    for(auto i : c_insert)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    
    
    //刪除
    map<int,int>::iterator erase_iter = c.begin();
    c.erase(erase_iter);
    cout <<"erase(): ";
    for(auto i : c)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    //指定下表刪除
    c.erase(10);
    cout <<"erase(): ";
    for(auto i : c)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    
    //指定元素刪除
    erase_iter = c.find(6);
    if(erase_iter != c.end())
    {
        cout<<"found index: "<< erase_iter->first <<endl;
        c.erase(erase_iter);
    }
    else{
        cout<< "Not found" <<endl;
    }
    for(auto i : c)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    
    
    //交換swap
    map<int, int> c_swap1;
    c_swap1.insert({pair<int, int>(1,10),pair<int, int>(2,20),pair<int, int>(3,30),pair<int, int>(4,40),pair<int, int>(5,50),pair<int, int>(6,60)});
    map<int, int> c_swap2;
    cout<<"swap() before: "<<endl;
    cout<<"c_swap1: ";
    for(auto i : c_swap1)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    
    cout<<"c_swap2: ";
    for(auto i : c_swap2)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    
    cout<<"swap() after: ";
    c_swap2.swap(c_swap1);
    cout<<"c_swap1: ";
    for(auto i : c_swap1)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    
    cout<<"c_swap2: ";
    for(auto i : c_swap2)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    
    //清除clear
    c_insert.clear();
    cout <<"clear(): ";
    for(auto i : c_insert)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    
    //elements() 插入 如果存在什么也不做 如果不存在插入
    map<int, int>::iterator element_iter = c_swap2.begin();
    
    auto xxx = c_swap2.emplace(pair<int, int>(7,60));
    if(xxx.second)
    {
        cout << "不存在" <<endl;
    }
    else
    {
        cout<< "存在" <<endl;
    }
    cout <<"elements(): ";
    for(auto i : c_swap2)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    
    //emplace_hint() 插入
    element_iter = c.emplace_hint(element_iter, pair<int, int>(7,60));
    cout <<"emplace_hint(): ";
    if(element_iter != c_swap2.end())
    {
        cout<< "存在" <<endl;
    }
    else{
        cout << "不存在" <<endl;
    }

 


 

五 操作函數

    //函數
    /*
     map<int, int> c;
     c.insert({pair<int, int>(1,10),pair<int, int>(2,20),pair<int, int>(3,30),pair<int, int>(4,40),pair<int, int>(5,50),pair<int, int>(6,60)});
     */
    //key_comp 返回key排序的函數 返回仿函數
    cout<<"key_comp(): " << c.key_comp()(1,2) <<endl; //會返回1  因為1<2
    cout<<"key_comp(): " << c.key_comp()(2,1) <<endl; //會返回0  因為2>1
    cout<<"key_comp(): " << c.key_comp()(1,1) <<endl; //會返回0  因為1=1
    
    //value_comp 返回取value和key數據包中的 取key函數 返回仿函數
    pair<int,int> value_comp_pair = *c.begin();
    iter = c.begin();
    cout << c.value_comp()(*iter++,value_comp_pair) << endl;

 


 

六 算法

//算法
    /*
     map<int, int> c;
     c.insert({pair<int, int>(1,10),pair<int, int>(2,20),pair<int, int>(3,30),pair<int, int>(4,40),pair<int, int>(5,50),pair<int, int>(6,60)});
     */
    //find()  指定key 返回對應pair
    cout <<"find(1): " << c.find(1)->second << endl;;

    
    //count()   key出現的次數
    cout <<"count(1): " << c.count(1)<< endl;;
    
    
    
    c.erase(4);
    
    //lower_bound 返回鍵值>=給定元素的第一個位置
    auto lower_boundObj = c.lower_bound(8);
    if(lower_boundObj->first)
        cout<<lower_boundObj->first<<endl;
    else
        cout<< "Not found lower_boundObj" << endl;
    
    for(auto i : c)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    
    //upper_bound 返回鍵值>給定元素的第一個位置
    auto upper_boundObj = c.upper_bound(4);
    if(upper_boundObj->first)
        cout<<upper_boundObj->first<<endl;
    else
        cout<< "Not found upper_bound" << endl;
    
    for(auto i : c)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    
    
    
    //equal_range()返回該元素所在區間(閉區間),返回值是一個pair<iterator, iterator>類型,first代表所在區間的起點迭代器,second表示所在區間的終點迭代器
    
    auto equal_rangeObj = c.equal_range(3);
    if(equal_rangeObj.first->first)
    {
        cout<<equal_rangeObj.first->first<<endl;
    }
    else
        cout<< "NOT equal_rangeObj.first" << endl;
    
    if(equal_rangeObj.second->second)
    {
        cout<<equal_rangeObj.second->first<<endl;
    }
    else
        cout<< "NOT second" << endl;

 

 


 七 自定義比較函數 map 默認為升序 改為降序

class my_compare_
{
public:
    bool operator()(int a, int b)
    {
        return a > b;
    }
};

int main(int argc, char *argv[])
{
    map<int, int, my_compare_> c;
    c.insert({pair<int, int>(1,10),pair<int, int>(2,20),pair<int, int>(3,30),pair<int, int>(4,40),pair<int, int>(5,50),pair<int, int>(6,60)});
    for(auto i : c)
    {
        cout<<"["<< i.first <<"] = " << i.second <<"  ";
    }
    cout << endl;
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM