C++ STL --map()与multimap()

 

Map和multimap将key/value pair(键值/实值 队组)当作元素,进行管理。他们根据key的排序准则将元素排序。multimap允许重复元素,map不允许。

元素要求:

  • key/value必须具有assigned(可赋值)和copyable(可复制的)性质。
  • 对于排序而言,key必须具是comparable(可比较的)。

                                           

典型情况下,set,multisets,map,multimap使用相同的内部结构,因此可以将set和multiset当成特殊的map和multimap,只不过set的value和key指向的是同一元素。

  map和multimap会根据key对元素进行自动排序,所以根据key值搜寻某个元素具有良好的性能,但是如果根据value来搜寻效率就很低了。

  同样,自动排序使得你不能直接改变元素的key,因为这样会破坏正确次序,要修改元素的key,必须先移除拥有key的元素,然后插入拥有新的key/value的元素,从迭代器的观点来看,元素的key是常数,元素的value是可以直接修改的。

                                              

Map由红黑树实现,其元素都是“键值/实值”所形成的一个对组(key/value pairs)。每个元素有一个键,是排序准则的基础。每一个键只能出现一次,不允许重复。Map主要用于资料一对一映射(one-to-one)的情况,map内部自建一颗红黑树(平衡二叉树中的一种),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的。比如一个班级中,每个学生的学号跟他的姓名就存在着一对一映射的关系。

头文件  #  include <map>

1、构造函数

map<int, string> a; //定义一个int类型的映射a
//map<int, string> a(10); //error,未定义这种构造函数
//map<int, string> a(10, 1); //error,未定义这种构造函数
map<int, string> b(a); //定义并用映射a初始化映射b
//map<int, string> b(a.begin(), a.end());  //error,未定义这种构造函数

代码

# include <iostream>
# include <map>
using namespace std;


template <class container>
void print(container con) 
{
    for (typename container::iterator it = con.begin(); it != con.end(); ++it)
    {
        cout << (*it).first << " " << (*it).second;
    }
    cout << endl;
}
int main()
{
    map<int, string> a; //定义一个int类型的映射a
    a.insert({ 1, "张三" });
    a.insert({ 2, "李四" });
    print(a);
    //map<int, string> a(10); //error,未定义这种构造函数
    //map<int, string> a(10, 1); //error,未定义这种构造函数
    map<int, string> b(a); //定义并用映射a初始化映射b
    print(b);
    map<int, string> c(a.rbegin(), a.rend());//默认升序
    print(c);

    multimap<int, string> d; //定义一个int类型的映射a
    d.insert({ 1, "张三" });
    d.insert({ 1, "李四" });
    print(d);
    //multimap<int, string> d(10); //error,未定义这种构造函数
    //multimap<int, string> d(10, 1); //error,未定义这种构造函数
    multimap<int, string> e(d); //定义并用映射a初始化映射b
    print(e);
    multimap<int, string> f(e.rbegin(), e.rend());
    print(f);

}

运行结果

2.增加函数

  • 在容器中插入元素:mp.insert(const T& x);
  • 任意位置插入一个元素: mp.insert(iterator it, const T& x);

代码

# include <iostream>
# include  <string>
# include <map>
using namespace std;
template <class container>

int main()
{
    map<char, int> mymap;

    // 第一个插入功能版本(单个参数):
    mymap.insert(pair<char, int>('a', 100));
    mymap.insert(pair<char, int>('z', 200));

    pair<map<char, int>::iterator, bool> ret;
    ret = mymap.insert(pair<char, int>('z', 500));
    if (ret.second == false) 
    {
        cout << "element 'z' already existed";
        cout << " with a value of " << ret.first->second << '\n';
    }

    // 第二个插入函数版本(带提示位置):
    map<char, int>::iterator it = mymap.begin();
    mymap.insert(it, pair<char, int>('b', 300));  // max efficiency inserting
    mymap.insert(it, pair<char, int>('c', 400));  // no max efficiency inserting

    // 第三个插入功能版本(范围插入):
    map<char, int> anothermap;
    anothermap.insert(mymap.begin(), mymap.find('c'));

    // showing contents:
    cout << "mymap contains:\n";

    for (it = mymap.begin(); it != mymap.end(); ++it)
        cout << it->first << " => " << it->second << '\n';

    cout << "anothermap contains:\n";

    for (it = anothermap.begin(); it != anothermap.end(); ++it)
        cout << it->first << " => " << it->second << '\n';

}

运行结果

 

代码2

# include <iostream>
# include <map>
# include <string>
using namespace std;

int main()
{
    map<int, string> mp;
    //在容器中插入元素
    mp.insert({ 1, "张三" });
    mp.insert({ 2, "李四" });
    //任意位置插入一个元素
    map<int, string>::iterator it = mp.begin();
    mp.insert(it, pair<int, string>{ 3, "隔壁老王" }); //会自动排序

    for (it = mp.begin(); it != mp.end(); it++)
        cout << it->first << " " << it->second << endl;
    cout << endl;

    return 0;
}

运行结果2

3.删除函数

  • 删除键值为keyValue的元素: mp.pop_back(const T& keyValue);
  • 删除迭代器所指的元素: mp.erase(iterator it);
  • 删除区间[first,last]之间的所有元素: mp.erase(iterator first, iterator last);
  • 清空所有元素: mp.clear();

代码

// erasing from map
#include <iostream>
#include <map>
using namespace std;

int main()
{
    map<char, int> mymap;
    map<char, int>::iterator it;

    // insert some values:
    mymap['a'] = 10;
    mymap['b'] = 20;
    mymap['c'] = 30;
    mymap['d'] = 40;
    mymap['e'] = 50;
    mymap['f'] = 60;

    it = mymap.find('b');
    mymap.erase(it);                   // erasing by iterator

    mymap.erase('c');                  // erasing by key

    it = mymap.find('e');
    mymap.erase(it, mymap.end());    // erasing by range

    // show content:
    for (it = mymap.begin(); it != mymap.end(); ++it)
        cout << it->first << " => " << it->second << '\n';

    return 0;
}

运行结果

 

代码2

#include <iostream>
#include <map>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
    map<int, string> mp;
    //在容器中插入元素
    mp.insert({ 1, "张三" });
    mp.insert({ 2, "李四" });
    mp.insert({ 4, "王五" });
    mp.insert({ 5, "小明" });
    //任意位置插入一个元素
    mp.insert(mp.begin(), pair<int, string>{ 3, "隔壁老王" }); //会自动排序

    //删除键值为keyValue的元素
    mp.erase(2);
    //删除迭代器所指的元素
    mp.erase(mp.begin());
    //删除区间[first,last]之间的所有元素
    mp.erase(mp.begin(), ++mp.begin());

    //display map
    map<int, string>::iterator it = mp.begin();
    for (it = mp.begin(); it != mp.end(); it++)
        cout << it->first << " " << it->second << endl;

    //清空容器内的所有元素
    mp.clear();

    //display map
    cout << "mp:";
    for (it = mp.begin(); it != mp.end(); it++)
        cout << it->first << " " << it->second << endl;
    cout << endl;

    return 0;
}

运行结果2

4. 迭代器

  • 开始迭代器指针:mp.begin();
  • 末尾迭代器指针:mp.end(); //指向最后一个元素的下一个位置
  • 指向常量的开始迭代器指针: mp.cbegin(); //意思就是不能通过这个指针来修改所指的内容,但还是可以通过其他方式修改的,而且指针也是可以移动的。
  • 指向常量的末尾迭代器指针: mp.cend();
  • 反向迭代器指针,指向最后一个元素: mp.rbegin();
  • 反向迭代器指针,指向第一个元素的前一个元素: mp.rend();
  • 返回键值大于等于key的迭代指针,否则返回end() : mp.lower_bound(keyElem);
  • 返回键值大于key的迭代指针,否则返回end() : mp.upper_bound(keyElem);
  • 返回容器中键值等于key的迭代指针[first,last) : mp.equal_range(keyElem);

代码

#include <iostream>
#include <map>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
    map<int, string> mp;
    //在容器中插入元素
    mp[1] = "张三";
    mp[2] = "李四";
    mp[3] = "隔壁老王";

    cout << "mp.begin()->first): " << mp.begin()->first << endl;
    cout << "(--mp.end())->first: " << (--mp.end())->first << endl;
    cout << "mp.cbegin()->first: " << mp.cbegin()->first << endl;
    cout << "(--mp.cend())->first : " << (--mp.cend())->first << endl;
    cout << "mp.rbegin()->first: " << mp.rbegin()->first << endl;
    cout << "(--mp.rend())->first: " << (--mp.rend())->first << endl;
    cout << "mp.lower_bound(2)->first: " << mp.lower_bound(2)->first << endl;
    cout << "mp.upper_bound(2)->first: " << mp.upper_bound(2)->first << endl;
    pair<map<int, string>::iterator, map<int, string>::iterator> t_pair = mp.equal_range(2);
    cout << "t_pair.first->first: " << t_pair.first->first << endl;
    cout << "t_pair.second->first: " << t_pair.second->first << endl;
    cout << endl;

    return 0;
}

运行结果

5.访问函数

可以使用at()函数和[]进行赋值运算

代码

// map::at
#include <iostream>
#include <string>
#include <map>
using namespace std;

int main()
{
    map<string, int> mymap = {  { "alpha", 0 }, { "beta", 0 },{ "gamma", 0 } };

    mymap.at("alpha") = 10;
    mymap.at("beta") = 20;
    mymap.at("gamma") = 30; 
    mymap.emplace("alpha", 100);
    mymap.emplace("y", 100);
    mymap.emplace("z", 200);
    pair< map<string, int>::iterator, bool> ret;
    ret = mymap.emplace("alpha", 100);
    cout << "mymap.emplace(\"alpha\", 100) = " << ret.second<<endl;

    for (auto& x : mymap) {
        cout << x.first << ": " << x.second << '\n';
    }



    map<char, int> mymap_1;
    map<char, int>::iterator it;
    char c;
    mymap_1['a'] = 50;
    mymap_1['b'] = 100;
    mymap_1['c'] = 150;
    mymap_1['d'] = 200;

    it = mymap_1.find('b');
    if (it != mymap_1.end())
        mymap_1.erase(it);

    // print content:
    cout << "elements in mymap:" << '\n';
    cout << "a => " << mymap_1.find('a')->second << '\n';
    cout << "c => " << mymap_1.find('c')->second << '\n';
    cout << "d => " << mymap_1.find('d')->second << '\n';
    for (c = 'a'; c < 'h'; c++)
    {
        cout << "mymap_1.count( " << c << " ) = " << mymap_1.count(c) << endl;

    }
    return 0;
}

运行结果

6.容量函数

  • 容器大小: mp.size();
  • 容器最大容量: mp.max_size();
  • 容器判空: mp.empty();
  • 查找键key的元素个数: mp.count(key);

代码

#include <iostream>
#include <map>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
    map<int, string> mp;
    mp.insert({ 1, "张三" });
    mp.insert({ 2, "李四" });
    mp.insert(pair<int, string>{ 3, "隔壁老王" });

    cout << "元素大小: " << mp.size() << endl;
    cout << "元素最大容量: " << mp.max_size() << endl;
    cout << "键2的元素个数: " << mp.count(2) << endl;
    if (mp.empty())
        cout << "元素为空" << endl;

    return 0;
}

运行结果

7.其他函数

  • 交换两个同类型容器的元素: swap(map&, map&); 或 mp.swap(map&);

代码

#include <iostream>
#include <map>
#include <string>

using namespace std;
int main()
{
    std::map<char, int> foo, bar;

    foo['x'] = 100;
    foo['y'] = 200;

    bar['a'] = 11;
    bar['b'] = 22;
    bar['c'] = 33;

    //swap(mp1,mp2); //ok
    foo.swap(bar);

    cout << "foo contains:\n";
    for (map<char, int>::iterator it = foo.begin(); it != foo.end(); ++it)
        cout << it->first << " => " << it->second << '\n';

    cout << "bar contains:\n";
    for (map<char, int>::iterator it = bar.begin(); it != bar.end(); ++it)
        cout << it->first << " => " << it->second << '\n';

    return 0;
}

运行结果

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值