C++11 STL: unordered_map使用入门

  • 背景:

hash_map 不是C++ 11 的标准

在vc中编译时:

#include 
using namespce stdext;
hash_map myhash;

在GCC中编译时:

#include 
using namespace _gnu_cxx;
hash_map myhash;
  • unordered_map:

在c++11 中, 加入了undered 系列的容器。undered_map 记录原始的hash值, 根据hash值判断元素是否相同。

查找,插入时:unordered_map > hash_map > map;

空间复杂度: hash_map < unordered_map < map;

unoedered_map 模板:

template <
    class Key,                         //key_type
    class T,                           //mapped_type
    class Hash = hash             //hasher
    class Pred = equal_to         //key_equal
    class Alloc = allocator>    //allocator_typr
>class unordered_map;
  • unoedered_map 迭代器:

迭代器是一个指针, 指向这个元素。

unordered_map::iterator it;
(*it).first;        //the key value(key_type:Key)
(*it).second;       //the mapped value(mapped_type:T)
(*it);              //the element value(type pair)

它的键值分别是迭代器的first和second属性。

 

  • undered_map 成员函数:

------------迭代器:

begin:    返回只想容器的起始位置迭代器(iterator)

end:       返回只想容器的末尾位置迭代器

cbegin:   返回指向容器起始位置的常迭代器(const_iterator)

cend:      返回指向容器末尾位置的常迭代器

-------------Capacity

size:             返回有效元素个数

max_size:    返回unordered_map 支持的最大元素个数

empty:          判断是否为空

-------------元素访问:

operator[]:           访问元素

at:                        访问元素

-------------迭代器修改:

insert:        插入元素

erase:         删除元素

swap:       交换内容

clear:          清空内容

emplace     构造以及插入一个元素

emplace_hint 按照提示构造以及插入一个元素

--------------------迭代器操作

find:        通过给定主键查找元素 ,没有找到: 返回unordered_map::end()

count:     返回匹配给定搜索值得元素得个数(可以看出, key值可以重复)

equal_rang:   返回值匹配给定搜索值得元素组成范围

------------------Buckets

bucket_count:            返回槽(Bucket)数

max_bucket_count:    返回最大槽数

bucket_size:               返回槽大小

bucket:                     返回元素所在槽序列号

load_factor:                 返回载入因子, 即一个元素槽(Bucket)的最大元素数

max_load_factor:        返回或者设置最大载入因子

rehash:                        设置槽数

reserve:                        请求改变容器数量

  • 插入元素示例:
// unordered_map::insert
#include 
#include 
#include 
using namespace std;

void display(unordered_map myrecipe,string str)
{
    cout << str << endl;
    for (auto& x: myrecipe)
        cout << x.first << ": " << x.second << endl;
    cout << endl;
}

int main ()
{
    unordered_map
    myrecipe,
    mypantry = {{"milk",2.0},{"flour",1.5}};

    /****************插入*****************/
    pair myshopping ("baking powder",0.3);
    myrecipe.insert (myshopping);                        // 复制插入
    myrecipe.insert (make_pair("eggs",6.0)); // 移动插入
    myrecipe.insert (mypantry.begin(), mypantry.end());  // 范围插入
    myrecipe.insert ({{"sugar",0.8},{"salt",0.1}});    // 初始化数组插入(可以用二维一次插入多个元素,也可以用一维插入一个元素)
    myrecipe["coffee"] = 10.0;  //数组形式插入

    display(myrecipe,"myrecipe contains:");

    /****************查找*****************/
    unordered_map::const_iterator got = myrecipe.find ("coffee");

    if ( got == myrecipe.end() )
        cout << "not found";
    else
        cout << "found "<first << " is " << got->second<<"\n\n";
    /****************修改*****************/
    myrecipe.at("coffee") = 9.0;
    myrecipe["milk"] = 3.0;
    display(myrecipe,"After modify myrecipe contains:");


    /****************擦除*****************/
    myrecipe.erase(myrecipe.begin());  //通过位置
    myrecipe.erase("milk");    //通过key
    display(myrecipe,"After erase myrecipe contains:");

    /****************交换*****************/
    myrecipe.swap(mypantry);
    display(myrecipe,"After swap with mypantry, myrecipe contains:");

    /****************清空*****************/
    myrecipe.clear();
    display(myrecipe,"After clear, myrecipe contains:");
    return 0;
}
/*
myrecipe contains:
salt: 0.1
milk: 2
flour: 1.5
coffee: 10
eggs: 6
sugar: 0.8
baking powder: 0.3

found coffee is 10

After modify myrecipe contains:
salt: 0.1
milk: 3
flour: 1.5
coffee: 9
eggs: 6
sugar: 0.8
baking powder: 0.3

After erase myrecipe contains:
flour: 1.5
coffee: 9
eggs: 6
sugar: 0.8
baking powder: 0.3

After swap with mypantry, myrecipe contains:
flour: 1.5
milk: 2

After clear, myrecipe contains:
*/
  • 遍历示例:
// unordered_map::bucket_count
#include 
#include 
#include 
using namespace std;

int main ()
{
    unordered_map mymap =
    {
        {"house","maison"},
        {"apple","pomme"},
        {"tree","arbre"},
        {"book","livre"},
        {"door","porte"},
        {"grapefruit","pamplemousse"}
    };
    /************begin和end迭代器***************/
    cout << "mymap contains:";
    for ( auto it = mymap.begin(); it != mymap.end(); ++it )
        cout << " " << it->first << ":" << it->second;
    cout << endl;
    /************bucket操作***************/
     unsigned n = mymap.bucket_count();

    cout << "mymap has " << n << " buckets.\n";

    for (unsigned i=0; ifirst << ":" << it->second << "] ";
        cout << "\n";
    }

    cout <<"\nkey:'apple' is in bucket #" << mymap.bucket("apple") <

 

原文链接:https://www.cnblogs.com/slothrbk/p/8823092.html

附加-leetcode 题目:

给定一个整数数组nums和一个目标值target, 请在该数组中找出和为目标值的那两个证书,并返回他们的数组下标。

假设每种输入只对应一个答案, 但是不能利用这个数组中相同的元素。

例如:nums = [2, 7, 11, 15], target = 9

因为nums[0] + nums[1] =  2 + 7 = 9

返回:[0, 1]

解答:

#include 
#include 
#include 

using namespace stdext;
using namespace std;
//<1、两遍哈希>
class Solution {
    vector twoSum(vector& nums, int target)
    {
        unordered_map m;
        for (int i = 0; i < nums.size(); ++i)
            m[nums[i]] = i;     //添加元素
        for (int i = 0; i < nums.size(); ++i)
        {
            if (m.find(target - nums[i]) != m.end() && m[target - nums[i]] != i) //如果m中存在对应的键值, 且不为i
                return { i, m[target - nums[i]] };
        }
        return {};
    }
};
//<1、一遍哈希>
class Solution {
    vector twoSum(vector& nums, int target)
    {
        unordered_map m;

        for (int i = 0; i < nums.size(); ++i)
        {
            if (m.find(target - nums[i]) != m.end()) //如果m中存在对应的键值, 且不为i
                return { m[target - nums[i]], i };
            m[nums[i]] = i; // 添加元素
        }
        return {};
    }
};

 

你可能感兴趣的:(STL)