【STL】map与set的使用方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dream_1996/article/details/78664226

使用set

set 是通过封装红黑树实现的key模型的搜索树,只有一个key值;除了搜索还可以快速的去重和排序;
set的key值不能被迭代器修改,但08版编译器有bug

定义set对象

std::set
template < class T,                        // set::key_type/value_type
           class Compare = less<T>,        // set::key_compare/value_compare
           class Alloc = allocator<T>      // set::allocator_type
           > class set;

第一个参数为插入set的数据类型
第二个为key值的比价仿函数,库里提供了两个比较自定义类型的仿函数:1.less//升序 2.greater//降序;这里缺省为less
- 三种定义set对象的方式

    //1.无参
    set<int, greater<int> > set1;
    for (int i = 1;i<6;i++)
        set1.insert(i);
    //set1的元素:5 4 3 2 1 

//2.给一个参数区间进行初始化
    int arr[] = { 1, 2, 3, 4, 5 };
    set<int> set2(arr, arr + 4);
    set<int> set4(set1.begin(), set1.end());
        //set2的结果:1 2 3 4 5
        //set4的结果:1 2 3 4 5

//3.要把自定义类型存入set,这里就需要自己写第二个比较参数。
    struct AA
    {
        int _a;
        int _b;
        AA(int a, int b)
            :_a(a)
            , _b(b)
        {}
    };
    struct ComLess //升序
    {
        bool operator()(const AA& left, const AA& right) const
        {
            return left._a < right._a;
        }
    };

    set<AA,ComLess> set3;
    set3.insert(AA(1,2));
    set3.insert(AA(3,4));
    set3.insert(AA(5,6));

find(key)

找到返回位置迭代器;没找到返回end迭代器

count()

key节点出现次数

insert插入

//c++ 98
insert (const value_type& val);
iterator insert (iterator position, const value_type& val);
void insert(InputIterator first, InputIterator last);
  • 直接插入
    上面定义set时使用insert直接插入一个值,insert直接插入时,返回一个pair,首先根据key值在底层红黑树里找合适的插入位置,如果此key值已经插入过,则返回当前值的迭代器和false;如果树里还没此节点,则插入并返回插入位置的迭代器和true。
    pair<set<int>::iterator,bool> Pair = set1.insert(5);
    if (Pair.second == false)
    {
        cout << "插入失败,说明5已经被插入过了" << endl;
    }
    else
    {
        cout << "插入成功,说明5在这次插入之前还没有,现在插入了" << endl;
    }
  • 通过find先找到插入结点之前的位置,这样insert的效率会高。
    set<int>::iterator it = set1.begin();
    it = set1.find(4);
    set1.insert(it,5);
  • 插入迭代器区间void insert(InputIterator first, InputIterator last);
    set<int> set5(set1.begin(), set1.end());

erase删除

c++ 98
(1) void erase (iterator position);
(2) size_type erase (const value_type& val);
(3) void erase (iterator first, iterator last)
  • 删除一个区间
    删除一个区间:给一个左闭右开的迭代器区间进行删除;这个迭代器区间的两个迭代器不能用find找,因为要找的值set里可能没有,则需要遍历找到满足这个区间的两个边界迭代器;
    lower_bound(val1)指找到大于等于val1的迭代器,
    upper_bound(val2)是找到大于val2的迭代器
    被删除的区间就是[val1,val2];
    set<int>::iterator left = set1.lower_bound(2);  //从左往右找到第一个大于等于2的位置
    set<int>::iterator right = set1.upper_bound(3); //从左往右找到第一个大于3的位置
    set1.erase(left, right); 
    //删除左开右闭区间,被删除的数为[2,3]
  • 删除一个迭代器位置
    set<int>::iterator It = set1.begin();
    It = set1.begin();
    set1.erase(It); 
  • 按值查找删除,删除成功返回1,删除失败返回0
    size_t i = set1.erase(5);
    cout << i << endl;  //1
    size_t j = set1.erase(1221);
    cout << j << endl;  //没有'1221',则返回0
}

map的使用

map是一个封装了红黑树的

templa class<k,v>
struct pair
{
    K first;
    v second;
}
  • make_pair()
    因为使用pair时,要指定模板类的类型,make_pair是模板函数,通过函数模板的特性,可以推演出参数的类型,然后返回一个pair的类,且不用指定模板参数类型。
template<class K, class V>
inline pair<K,V> make_pair(const K& key, const V& value)
{
    return pair<K,V>(key,value);    
}

map 和set的使用都差不多,要注意的就是map许多接口返回的迭代器是存一个pair的结点的迭代器,如Insert,find,erase等,pair的first是key值,second是value值。但set返回的迭代器是一个存key值的迭结点的代器。map比set多的一个比较有特点的接口,就是map重载了operator[],在下面有对operator[]的介绍。其余的操作map和set
都差不多。

Insert插入

  • insert(pair
    map<int,int> map1;
    pair<map<int,int>::iterator, bool> ret2 = map1.insert(make_pair(1,2));
    cout << ret2.first->first << ":" << (*(ret2.first)).second << endl;   //运行结果:1 :2
  • map插入数据并统计相同的Key出现的次数
//1.返回值是一个pair,插入成功pair的second为true
pair<map<string,int>::iterator, bool> kvRet = insert(pair<string,int>(str[i],1));
if(kvRet == false)
{
    kvRet.first->second++;
}

//2.operator[]
CountMap[str[i]]++;
  • operator[]
    根据k值访问map,返回value的引用,即可读也可以修改value。
    若k不存在,则插入k,value为缺省值。因此可以这样插入 dict[“insert”] = “插入”。
//mapped_type是value类型,mapped_type()是value的缺省值
mapped_type& operator[](const K& k)
{
    return (*((this->insert(make_pair(k,mappde_type()))).first)).second  
}

multimap

  • 允许键值冗余
  • 没有operator[]

multiset

  • 允许键值冗余
  • find查找的是中序的第一个

猜你喜欢

转载自blog.csdn.net/dream_1996/article/details/78664226
今日推荐