c++ 11标准模板(STL) std::map(三)旧

本文详细解读了C++ map容器的count(), find(), equal_range(), lower_bound(), 和 upper_bound() 函数,展示了如何使用这些方法获取元素数量、查找特定键、查找区间及边界迭代器。通过实例演示,读者将掌握map在实际编程中的应用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

查找

返回匹配特定键的元素数量

std::map<Key,T,Compare,Allocator>::count

函数

size_type count( const Key& key ) const;

返回拥有关键比较等价于指定参数的元素数,因为此容器不允许重复故为 1 或 0。

参数

key-要计量元素数的关键值

返回值

拥有比较等价于 key 的关键的元素数,对于 (1) 为 1 或 0。

复杂度

与容器大小成对数。

示例

    cout << "countTest() begin" << endl;
    map<uint16_t, string, std::less<uint16_t>> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    cout << "map1.count(1): " << map1.count(1) << endl;
    cout << "map1.count(6): " << map1.count(6) << endl;
    cout << "countTest() end" << endl;

 

寻找带有特定键的元素

std::map<Key,T,Compare,Allocator>::find

函数

iterator find( const Key& key );                             (1)  

const_iterator find( const Key& key ) const;                (2) 

 1,2) 寻找键等于 key 的的元素。

参数

key-要搜索的元素键值

返回值

指向键等于 key 的元素的迭代器。若找不到这种元素,则返回尾后(见 end() )迭代器。

复杂度

与容器大小成对数。

示例

    cout << "countTest() begin" << endl;
    map<uint16_t, string, std::less<uint16_t>> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    map<uint16_t, string>::const_iterator it = map1.find(1);
    cout << "map1.find(1): " << "key:   " << (it == map1.end() ? "find no" : it->second) << endl;
    auto  it2 = map1.find(6);
    cout << "map1.find(6): " << "key:   " << (it2 == map1.end() ? "find no" : it2->second) << endl;
    cout << "countTest() end" << endl;

返回匹配特定键的元素范围

std::map<Key,T,Compare,Allocator>::equal_range

函数

std::pair<iterator,iterator> equal_range( const Key& key );                        (1)  

std::pair<const_iterator,const_iterator> equal_range( const Key& key ) const;      (2) 

返回容器中所有拥有给定关键的元素范围。范围以二个迭代器定义,一个指向首个不小于 key 的元素,另一个指向首个大于 key 的元素。首个迭代器可以换用 lower_bound() 获得,而第二迭代器可换用 upper_bound() 获得。

1,2) 比较关键与 key

参数

key-要比较元素的关键值
x-能与 Key 比较的替用值

返回值

含一对定义所需范围的迭代器的 std::pair :第一个指向首个不小于 key 的元素,第二个指向首个大于 key 的元素。

若无元素不小于 key ,则将尾后(见 end() )迭代器作为第一元素返回。类似地,若无元素大于 key ,则将尾后迭代器作为第二元素返回。

复杂度

与容器大小成对数。

示例

    cout << "equal_rangeTest() begin" << endl;
    map<uint16_t, string, std::less<uint16_t>> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    std::pair<map<uint16_t, string>::iterator, map<uint16_t, string>::iterator> it = map1.equal_range(1);
    cout << "map1.equal_range(1): " << endl;
    cout << "it.first   " << (it.first == map1.end() ? "find no"  : it.first->second) << endl;
    cout << "it.second  " << (it.second == map1.end() ? "find no"  : it.second->second) << endl;
    auto it2 = map1.equal_range(6);
    cout << "map1.equal_range(6): " << endl;
    cout << "it2.first   " << (it2.first == map1.end() ? "find no"  : it2.first->second) << endl;
    cout << "it2.second  " << (it2.second == map1.end() ? "find no"  : it2.second->second) << endl;
    cout << "equal_rangeTest() end" << endl;

 返回指向首个不小于给定键的元素的迭代器

std::map<Key,T,Compare,Allocator>::lower_bound

函数

iterator lower_bound( const Key& key );                     (1)  

const_iterator lower_bound( const Key& key ) const;         (1) 

1) 返回指向首个不小于 key 的元素的迭代器。

参数

key-要与元素比较的关键值

返回值

指向首个不小于 key 的元素的迭代器。若找不到这种元素,则返回尾后迭代器(见 end() )。

复杂度

与容器大小成对数。

示例

    cout << "lower_boundTest() begin" << endl;
    map<uint16_t, string, std::less<uint16_t>> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    map<uint16_t, string>::iterator it = map1.lower_bound(1);
    cout << "map1.lower_bound(1): " << "key:   " << (it == map1.end() ? "find no" : it->second) << endl;
    auto it1 = map1.lower_bound(6);
    cout << "map1.lower_bound(6): " << "key:   " << (it1 == map1.end() ? "find no" : it1->second) << endl;
    cout << "lower_boundTest() end" << endl;

 返回指向首个大于给定键的元素的迭代器

std::map<Key,T,Compare,Allocator>::upper_bound

函数

iterator upper_bound( const Key& key );                        (1)  

const_iterator upper_bound( const Key& key ) const;            (1) 

1) 返回指向首个大于 key 的元素的迭代器。

参数

key-与元素比较的关键值

返回值

指向首个大于 key 的元素的迭代器。若找不到这种元素,则返回尾后(见 end() )迭代器。

复杂度

与容器大小成对数。

示例

    cout << "upper_boundTest() begin" << endl;
    map<uint16_t, string, std::less<uint16_t>> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    map<uint16_t, string>::iterator it = map1.upper_bound(1);
    cout << "map1.upper_bound(1): " << "key:   " << (it == map1.end() ? "find no" : it->second) << endl;
    auto it1 = map1.upper_bound(6);
    cout << "map1.upper_bound(6): " << "key:   " << (it1 == map1.end() ? "find no" : it1->second) << endl;
    cout << "upper_boundTest() end" << endl;

代码汇总

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

using namespace std;

struct myCompare
{
    bool operator()(const uint16_t a, const uint16_t b) const
    {
        return (a > b);
    }
    myCompare() {}
};

template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
          typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
void print_Map(const string &name, const map<_Key, _Tp, _Compare, _Alloc> &tmap)
{
    cout << name << ": \n";
    for (const std::pair<const _Key, _Tp> it : tmap)
    {
        cout << "key: " << it.first << ", value: " << it.second << endl;
    }
}

void constructorTest()
{
    cout << "constructorTest() begin" << endl;
    // 构造空容器
    map<uint16_t, string> map1;
    cout << "map1.size() : " << map1.size() << endl;

    // 列表初始化,构造, 排序递增
    map<uint16_t, string, std::less<uint16_t>> map2{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("initializer_list, ASC", map2);
    // 列表初始化,构造, 排序递减
    map<uint16_t, string, std::greater<uint16_t>> map6{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("initializer_list, DESC", map6);
    // 列表初始化,构造, 排序自定义
    map<uint16_t, string, myCompare> map7{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("initializer_list, DESC", map7);

    // 范围构造,排序递增
    map<uint16_t, string, std::less<uint16_t>> map3(map2.begin(), map2.end());
    print_Map("range, ASC", map3);
    // 范围构造,排序递减
    map<uint16_t, string, std::greater<uint16_t>> map8(map2.begin(), map2.end());
    print_Map("range, DESC", map8);


    // 拷贝构造,类型必须一致,包括排序,排序递增
    map<uint16_t, string, std::less<uint16_t>> map4(map3);
    print_Map("copy, ASC", map4);
    // 拷贝构造,排序递增
    map<uint16_t, string, std::greater<uint16_t>> map9(map8);
    print_Map("copy, DESC", map9);

    // 赋值构造,类型必须一致,包括排序,排序递增
    map<uint16_t, string, std::less<uint16_t>> map10 = map4;
    print_Map("assignment , ASC", map10);
    // 赋值构造,类型必须一致,包括排序,排序递减
    map<uint16_t, string, std::greater<uint16_t>> map11 = map9;
    print_Map("assignment , DESC", map11);

    cout << "constructorTest() end" << endl;
}

void elementAccessTest()
{
    cout << "elementAccessTest() begin" << endl;
    map<uint16_t, string, std::less<uint16_t>> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    cout << "at(key) : " << map1.at(1) << endl;
    cout << "[key] : " << map1[2] << endl;
    // map容器产生<6,"">节点
    cout << "[key] : " << map1[6] << endl;
    print_Map("[key] , ASC", map1);
    // map容器产生<7,"H">节点
    map1[7] = "H";
    print_Map("[key] , ASC", map1);
    // map容器key为1的节点value被替换为"K"
    map1[1] = "K";
    print_Map("[key] , ASC", map1);
    cout << "elementAccessTest() end" << endl;
}

void capacityTest()
{
    cout << "capacityTest begin" << endl;
    map<uint16_t, string> map1;
    cout << "map1: " << (map1.empty() ? "empty" : "not empty");
    cout << "map1 size() " << map1.size() << endl;;
    map1[1] = "A";
    map1[2] = "B";
    cout << "map1: " << (map1.empty() ? "empty" : "not empty");
    cout << "map1 size() " << map1.size() << endl;;
    cout << "map<uint16_t, string> max_size: " << map1.max_size() << std::endl;
    map<uint16_t, uint16_t> map2;
    cout << "map<uint16_t, uint16_t> max_size: " << map2.max_size() << std::endl;
    map<string, uint16_t> map3;
    cout << "map<string, uint16_t> max_size: " << map3.max_size() << std::endl;
    map<string, string> map4;
    cout << "map<string, string> max_size: " << map4.max_size() << std::endl;
    cout << "capacityTest end" << endl;
}

void iteratorTest()
{
    cout << "iteratorTest begin" << endl;
    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    // 遍历容器, const_iterator
    std::cout << "const_iterator:\n";
    for (map<uint16_t, string>::const_iterator it = map1.cbegin(); it != map1.cend(); it++)
    {
        cout << "key: " << it->first << ", value: " << it->second << endl;
    }
    std::cout << "const_iterator:\n";
    for (map<uint16_t, string>::const_reverse_iterator it = map1.crbegin(); it != map1.crend(); it++)
    {
        cout << "key: " << it->first << ", value: " << it->second << endl;
    }

    std::cout << "begin():   " << std::hex << (int)&*map1.begin() << std::endl;
    std::cout << "cbegin():  " << std::hex << (int)&*map1.cbegin() << std::endl;
    std::cout << "end():     " << std::hex << (int)&*map1.end() << std::endl;
    std::cout << "cend():    " << std::hex << (int)&*map1.cend() << std::endl;
    std::cout << "rbegin():  " << std::hex << (int)&*map1.rbegin() << std::endl;
    std::cout << "crbegin(): " << std::hex << (int)&*map1.crbegin() << std::endl;
    std::cout << "rend():    " << std::hex << (int)&*map1.rend() << std::endl;
    std::cout << "crend():   " << std::hex << (int)&*map1.crend() << std::endl;

    cout << "iteratorTest end" << endl;
}

void clearTest()
{
    cout << "clearTest() begin" << endl;
    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("clear before", map1);
    map1.clear();
    cout << "map1: " << (map1.empty() ? "empty" : "not empty");
    cout << "clearTest() end" << endl;
}

void insertTest()
{
    cout << "insertTest() begin" << endl;
    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
    print_Map("insert before", map1);
    std::pair<std::map<uint16_t, string>::iterator, bool> itI = map1.insert({4, "D"});
    cout << "insert " << (itI.second ? "success" : "fail") ;
    cout << " key: " << itI.first->first << " value: " << itI.first->second <<  endl;
    print_Map("insert after", map1);

    map<uint16_t, string>::const_iterator pIt = map1.find(2);
    cout << "find key: " << pIt->first << " value: " << pIt->second << endl;

    map<uint16_t, string>::const_iterator nIt = map1.insert(pIt, {5, "E"});
    cout << "insert key: " << nIt->first << " value: " << nIt->second << endl;
    print_Map("insert after", map1);

    map<uint16_t, string> map2{{6, "F"}, {7, "H"}};
    map2.insert(map1.begin(), map1.end());
    print_Map("map2 insert after", map2);
    cout << "insertTest() end" << endl;
}

void emplaceTest()
{
    cout << "emplaceTest() begin" << endl;
    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
    print_Map("emplace before", map1);

    std::pair<std::map<uint16_t, string>::iterator, bool> itI = map1.emplace(make_pair(4, "D"));
    cout << "emplace " << (itI.second ? "success" : "fail") ;
    cout << " key: " << itI.first->first << " value: " << itI.first->second <<  endl;
    print_Map("emplace after", map1);

    map<uint16_t, string>::const_iterator pIt = map1.find(2);
    map<uint16_t, string>::const_iterator nIt = map1.emplace_hint(pIt, make_pair(5, "E"));
    cout << "emplace_hint key: " << nIt->first << " value: " << nIt->second << endl;
    print_Map("emplace_hint after", map1);

    cout << "emplaceTest() end" << endl;
}

void eraseTest()
{
    cout << "eraseTest() begin" << endl;
    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("erase before", map1);
    size_t ct = map1.erase(3);
    cout << "erase size: " << ct << std::endl;
    ct = map1.erase(3);
    cout << "erase size: " << ct << std::endl;
    print_Map("map1 erase after", map1);

    map<uint16_t, string>::const_iterator pIt = map1.find(2);
    map<uint16_t, string>::const_iterator eIt = map1.erase(pIt);
    cout << "erase key: " << eIt->first << " value: " << eIt->second << endl;
    print_Map("map1 erase after", map1);

    map<uint16_t, string> map2{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("map2 erase before", map2);
    map2.erase(map2.begin(), map2.end());
    print_Map("map2 erase after", map2);
    cout << "eraseTest() end" << endl;
}

void swapTest()
{
    cout << "swapTest() begin" << endl;
    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
    map<uint16_t, string> map2{{4, "D"}, {5, "E"}};
    print_Map("map1 swap before", map1);
    print_Map("map2 swap before", map2);
    map1.swap(map2);
    print_Map("map1 swap after", map1);
    print_Map("map2 swap after", map2);
    cout << "swapTest() end" << endl;
}

void countTest()
{
    cout << "countTest() begin" << endl;
    map<uint16_t, string, std::less<uint16_t>> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    cout << "map1.count(1): " << map1.count(1) << endl;
    cout << "map1.count(6): " << map1.count(6) << endl;
    cout << "countTest() end" << endl;
}

void findTest()
{
    cout << "countTest() begin" << endl;
    map<uint16_t, string, std::less<uint16_t>> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    map<uint16_t, string>::const_iterator it = map1.find(1);
    cout << "map1.find(1): " << "key:   " << (it == map1.end() ? "find no" : it->second) << endl;
    auto  it2 = map1.find(6);
    cout << "map1.find(6): " << "key:   " << (it2 == map1.end() ? "find no" : it2->second) << endl;
    cout << "countTest() end" << endl;
}

void equal_rangeTest()
{
    cout << "equal_rangeTest() begin" << endl;
    map<uint16_t, string, std::less<uint16_t>> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    std::pair<map<uint16_t, string>::iterator, map<uint16_t, string>::iterator> it = map1.equal_range(1);
    cout << "map1.equal_range(1): " << endl;
    cout << "it.first   " << (it.first == map1.end() ? "find no"  : it.first->second) << endl;
    cout << "it.second  " << (it.second == map1.end() ? "find no"  : it.second->second) << endl;
    auto it2 = map1.equal_range(6);
    cout << "map1.equal_range(6): " << endl;
    cout << "it2.first   " << (it2.first == map1.end() ? "find no"  : it2.first->second) << endl;
    cout << "it2.second  " << (it2.second == map1.end() ? "find no"  : it2.second->second) << endl;
    cout << "equal_rangeTest() end" << endl;
}

void lower_boundTest()
{
    cout << "lower_boundTest() begin" << endl;
    map<uint16_t, string, std::less<uint16_t>> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    map<uint16_t, string>::iterator it = map1.lower_bound(1);
    cout << "map1.lower_bound(1): " << "key:   " << (it == map1.end() ? "find no" : it->second) << endl;
    auto it1 = map1.lower_bound(6);
    cout << "map1.lower_bound(6): " << "key:   " << (it1 == map1.end() ? "find no" : it1->second) << endl;
    cout << "lower_boundTest() end" << endl;
}

void upper_boundTest()
{
    cout << "upper_boundTest() begin" << endl;
    map<uint16_t, string, std::less<uint16_t>> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    map<uint16_t, string>::iterator it = map1.upper_bound(1);
    cout << "map1.upper_bound(1): " << "key:   " << (it == map1.end() ? "find no" : it->second) << endl;
    auto it1 = map1.upper_bound(6);
    cout << "map1.upper_bound(6): " << "key:   " << (it1 == map1.end() ? "find no" : it1->second) << endl;
    cout << "upper_boundTest() end" << endl;
}

int main()
{
//    constructorTest();
//    elementAccessTest();
//    capacityTest();
//    iteratorTest();
//    clearTest();
//    insertTest();
//    emplaceTest();
//    eraseTest();
//    swapTest();
    countTest();
    findTest();
    equal_rangeTest();
    lower_boundTest();
    upper_boundTest();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值