C++关联式容器set,multiset

5 篇文章 0 订阅

set和multiset都是C++标准库中的一种关联式容器,它们都会依照一定的规则对存放到其中的元素进行排序,它们俩个主要区别在于:multiset里面的元素可以重复,而set也就类似于数学中的集合,不出现重复元素。
它们在C++标准库中的定义如下:

namespace std {
    template <class T, 
            class Compare = less<T>,
            class Allocator = allocator<T>>
    class set;
    template <class T, 
            class Compare = less<T>,
            class Allocator = allocator<T>>
    class multiset;
}

通过上面的模板参数,我们可以看出来,在使用这两个类时,我们可以传入三个参数:容器中的元素类型,比较器的类型(主要用于对元素进行排序),内存模型(缺省值allocator由C++标准库提供)。比较器的缺省类型为less,这是一个仿函数,以operator<对元素进行比较。
set和multiset通常由平衡二叉树实现,能够实现元素在存储时的自动排序,但是自动排序还有一个缺点就是,排序后我们不能对元素在原来位置上进行修改,那会打乱原来元素排列的正确顺序,要改变元素值我们必须先取出旧的元素,修改后,重新插入到集合中去。
set和multiset中几个比较特殊的方法:

count(e)    //返回值为e的元素的个数
find(e)     //返回只想元素值为e的第一个元素的迭代器,如果没有找到就返回end()
lower_bound(e) //返回第一个可插入元素的位置,也就是元素值>=e
upper_bound(e) //返回最后一个可插入元素的位置,也就是元素值>e
equal_range(e) //返回可插入元素的第一个位置和最后一个位置,也即是元素值==e的元素区间

上述函数的测试用例如下:

#include "stdafx.h"
#include <set>
#include <iostream>

using namespace std;

class setClass{
private:
    int num;
public:
    setClass(int val) :num(val){

    }
    virtual ~setClass(){}
    friend ostream& operator<<(ostream& os, const setClass& sc);
    friend bool operator<(const setClass& c1, const setClass& c2);
};
bool operator<(const setClass& c1, const setClass& c2){
    return c1.num < c2.num;
}
ostream& operator<<(ostream& os, const setClass& sc){
    os << sc.num << endl;
    return os;
}
void setTest(){
    multiset<setClass> sc;
    sc.insert(1);       //因为setClass有接受int的构造函数,这里直接传入int值会有一步自动转换
    sc.insert(2);
    sc.insert(3);
    sc.insert(3);
    sc.insert(3);
    sc.insert(3);
    sc.insert(4);
    sc.insert(5);
    sc.insert(6);
    sc.insert(7);
    sc.insert(8);

    cout << sc.count(3) << endl; // 4
    multiset<setClass>::iterator index = sc.begin();
    index++;
    index++;
    if (index == sc.find(3)) {//true
        cout << "sc.begin() + 2 == sc.find(3)" << endl;  
    }
    multiset<setClass>::iterator index3 = index;
    if (index3 == sc.lower_bound(3)){ //true sc.lower_bound(3) 返回指向第一个元素为3的向量
        cout << "sc.begin() + 2 == sc.lower_bound(3)" << endl;
    }
    index++;
    index++;
    index++;
    index++;
    multiset<setClass>::iterator index4 = index;
    if (index4 == sc.upper_bound(3)){  //true sc.upper_bound(3) 返回指向最后一个元素为3的下一个向量  元素为4
        cout << "sc.begin() + 6 == sc.lower_bound(3)" << endl;
    }

    pair<multiset<setClass>::iterator, multiset<setClass>::iterator> retindex = sc.equal_range(3);
    if ((retindex.first == index3) && (retindex.second == index4)){
        cout << "equal_range返回值得上下限,分别为lower_bound, upper_bound的返回值" << endl;
    }

}

int _tmain(int argc, _TCHAR* argv[])
{
    setTest();
    system("pause");
    return 0;
}

另外,set和multiset的安插函数的型别也不相同:
set提供的接口如下:

pair<iterator, bool> insert(const type_value& value);
iterator insert(iterator pos, const type_value& value);

multiset提供的接口如下:

iterator insert(const type_value& value);
iterator insert(iterator pos, const type_value& value);

两者返回值不同的原因,主要是因为set不允许重复元素,而multiset允许重复元素,set通过返回一个pair把一个位置迭代器指针和bool型组织起来,主要是为了,通过bool值表示插入是否成功,如果成功了说明返回的iterator中存储的元素位置为新元素的位置,如果bool为flase,说明相同值的元素已经在集合中存在,通过iterator返回,已存在的元素的位置。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值