无序关联容器

无序关联容器
底层:哈希表 增删查时间复杂度都是O(n);
set:集合 key map:映射表 [key,value]
unordered_set :单重集合
unordered_multiset:多重集合
unordered_map:单重映射表
unordered_multimap:单充映射表

使用无序关联容器包含的头文件
#include <unordered_set>
#include <uordered_map>

**

set集合:

**
常用方法函数:
增加:insert(val);
遍历:iterator; find(it);
删除:erase(val); erase(it);

#include <iostream>
#include <unordered_set>
#include <unordered_map>
using namespace std;
int main()
{
    unordered_set<int> set1;//不会储存key值重复的元素
    for (int i = 0; i < 50; ++i)
    {
        set1.insert(rand() % 100 + 1);
    }
    cout << set1.size() << endl;
    cout << set1.count(15) << endl;
    return 0;
}

运行结果如下:
在这里插入图片描述
容器中有41个元素,15出现了0次,对于单重集合来讲,只会储存不重复的元素。
修改程序为多重集合后:

#include <iostream>
#include <unordered_set>
#include <unordered_map>
using namespace std;
int main()
{
    unordered_multiset<int> set1;//不会储存key值重复的元素
    for (int i = 0; i < 50; ++i)
    {
        set1.insert(rand() % 100 + 1);
    }
    cout << set1.size() << endl;
    cout << set1.count(15) << endl;
    return 0;
}

在这里插入图片描述
发现50个元素都存进去了,多重集合可以存放重复的元素。

set的增删改查例子:

#include <iostream>
#include <unordered_set>
#include <unordered_map>
using namespace std;
int main()
{
    unordered_set<int> set1;//不会储存key值重复的元素
    for (int i = 0; i < 50; ++i)
    {
        set1.insert(rand() % 100 + 1);
    }
   /* cout << set1.size() << endl;
    cout << set1.count(15) << endl;*/
    auto it1 = set1.begin();
    for (; it1 != set1.end(); ++it1)
    {
        cout << *it1 << " ";
    }
    cout << endl;
    set1.erase(20);
    for (it1 = set1.begin(); it1 != set1.end(); )
    {
        if (*it1 == 30)
        {
            it1 = set1.erase(it1);//注意迭代器失效问题
        }
        else
        {
            ++it1;
        }
    }
    it1 = set1.find(20);//find失败会返回容器的末尾迭代器
    if (it1 != set1.end())
    {
        set1.erase(it1);
    }
    return 0;
}

**

map映射表

**
插入的不是一个值,而是键值对,[key,value]

#include <iostream>
#include <unordered_set>
#include <unordered_map>
#include <string>
using namespace std;
int main()
{

    
    unordered_map<int, string> map1;
    map1.insert(make_pair(1000, "张三"));//把一个键值对打包在一起
    map1.insert({ 1010,"李四" });//也可以用一个大括号来打包
    map1.insert({ 1020,"王五" });
    map1.insert({ 1010,"王凯" });//单重集合不允许重复
    map1.insert({ 1030,"吴亮" });

    map1.erase(1020);//删除

    cout << map1.size() << endl;
    //map还提供了[]的重载函数  operator[](key) =>value 
    //[]不仅有查询的作用,如果key不存在,它会插入一对数据[key,string()]
    cout << map1[1000] << endl; 
    map1[2000] = "刘欢";//2000不存在,会创建
    map1[2000] = "何水";//2000存在,会修改
    cout << map1[2000] << endl;
    auto it1 = map1.find(1030);
    if (it1 != map1.end())
    {
        cout << "key: " << it1->first << " " << "value: " << it1->second << endl;
    }
    return 0;
}

在这里插入图片描述

map映射表常常用来处理海量数据去重,例如现在有十万个整数,让我们去统计哪些数字重复了,并统计数字重复的次数:

#include <iostream>
#include <unordered_set>
#include <unordered_map>
#include <string>
using namespace std;
int main()
{
    const int ARR_LEN = 100000;
    int arr[ARR_LEN] = { 0 };
    for (int i = 0; i < ARR_LEN; ++i)
    {
        arr[i] = rand() % 100000 + 1;
    }
    unordered_map<int, int> map1;
    for (int k : arr)
    {
       /* auto it = map1.find(k);
        if (it == map1.end())
        {
            map1.insert({k,1});
        }
        else
        {
            it->second++;
        }*/
        map1[k]++;
    }
    auto it = map1.begin();
    for (; it != map1.end();++it)
    {
        if (it->second > 1)
        {
            cout << "key: " << it->first << "count: " << it->second << endl;
        }
    }
 /*   for (pair<int, int> p : map1)
    {
        if (p.second > 1)
        {
            cout << "key: " << p.first << "count: " << p.second << endl;
        }
    }*/
    return 0;
}

对海量数据进行去重打印:

#include <iostream>
#include <unordered_set>
#include <unordered_map>
#include <string>
using namespace std;
int main()
{
    const int ARR_LEN = 10;
    int arr[ARR_LEN] = { 0 };
    for (int i = 0; i < ARR_LEN; ++i)
    {
        arr[i] = rand() % 10 + 1;
    }
    unordered_set<int> set;
    for (int k : arr)
    {
        set.insert(k);
    }
    for (int v : set)
    {
        cout << v << " ";
    }
    cout << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值