map与set的使用

1、关联式容器

我们一开始接触的STL容器例如:vector,list,queue等这些容器统称为序列式容器,因为这些容器的底层为线性的数据结构,里面存储的是元素本身。

关联式容器也是用来存储数据的,不同的是里面存储的是<key, value>结构的键值对,在进行数据检索的效率更高

2.键值对

用来表示一一对应关系的数据结构,该数据结构通常有两个成员变量key和value,其中key表示键值,value表示key对应的信息。例如中英词典,将英文作为key,中文翻译作为value,这样通过一一对应的关系,我们可以使用英文找到对应的中文翻译。

3.set

set支持直接插入,也可以使用花括号或者迭代器初始化。

    //插入
    //set<int> s;
    //s.insert(1);
    //s.insert(4);
    //s.insert(2);
    
    //set<int> s = { 1, 4, 2 };花括号初始化


    //迭代器初始化
    vector<int> v = { 1, 4, 2 };
    set<int> s(v.begin(), v.end());

set可以使用迭代器进行数据遍历,支持迭代器也就可以使用范围for,范围for的底层原理就是使用迭代器遍历。


    set<int>::iterator it = s.begin();
    while (it != s.end())
    {
        cout << *it << " ";
        ++it;
    }
    cout << endl;
    for (auto e : s)
    {
        cout << e << " ";
    }

当我们向set中插入相同元素时,set会将进行去重,并排序,即不插入相同的元素,这里的排序,是指进行的中序遍历。

我们使用erase进行元素删除时需要注意一点:下面的的find函数没有找到对应的元素时会返回迭代器的end位置,这样直接传入迭代器进行删除会报错。

    set<int>::iterator pos = s.find(3);
    s.erase(pos);

需要加上如下代码示例

    set<int>::iterator pos = s.find(3);
    if (pos != s.end())
    s.erase(pos);

4.multiset

multiset和set的使用基本上没有什么差别,就是multiset可以插入重复的值。

下面这段代码输出结果为(表明find返回的值为中序遍历中第一个迭代器)

1 2 2 3 3 3
3 3 3

    multiset<int> ms = {3, 1 ,2 ,3, 2, 3};
    for (auto e : ms)
    {
        cout << e << " ";
    }
    cout << endl;
    auto mspos = ms.find(3);
    while (mspos != ms.end())
    {
        cout << *mspos << " ";
        mspos++;
    }

使用删除时,删除所有元素,除非你给的参数为迭代器。

5.map

map内存储的是pair结构体。下图为pair的结构

下面介绍3种插入方式

    map<string, string> dict;
    //创建pair对象进行插入
    //pair<string, string> kv("right", "右");
    //dict.insert(kv);

    //创建pair匿名对象进行插入
    //dict.insert(pair<string, string>("right", "右"));
    //typedef pair<string, string> kv;
    //dict.insert(kv("right", "右"));

    dict.insert(make_pair("right", "右"));//通常这样插入比较方便

使用迭代器遍历(这里迭代器返回的是pair结构体指针)所以我们也可以使用it->first的方式进行访问。

    dict.insert(make_pair("right", "右"));//通常这样插入比较方便
    dict.insert(make_pair("left", "左"));
    dict.insert(make_pair("good", "好"));

    auto it = dict.begin();
    while (it == dict.end())
    {
        cout << (*it).first << ' ' << it->second;
        it++;
    }
    cout << endl;

    return 0;

值得一提的是map是支持使用[]进行访问的(使用[]时如果找到了该元素则返回pair中的second引用,如果没有该元素,则将该元素插入后再返回对应的pair的second的引用)所以下面的代码对arr数组中的元素进行了统计次数的操作。

    map<string, int> countMap;
    string arr[] = {"1a", "2b", "2b", "3c", "3c", "3c"};
    for (auto& str : arr)
    {
        countMap[str]++;
    }
    for (auto it : countMap)
    {
        cout << it.first << ": " << it.second << endl;
    }

下面为对[]操作符的重载(insert会返回一个pair<iterator, bool>类型的结构体,map中没有该元素插入返回插入成功的的迭代器,布尔值为true,map中已经有该元素,返回已存在的迭代器,布尔值为false)所以不管插入成功与否都会返回该元素的迭代器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值