C++中的 set和multiset

C++ multiset详解
本文详细介绍了C++中multiset容器的特性和用法,包括其作为关联容器的性质、排序规则、常用成员函数及其与set的区别。适用于C++开发者深入了解和应用multiset。

multiset是关联容器,是排好序的集合,并且集合中的元素可以重复
因为是关联容器,所以想要更改一个元素的值需要先删除再添加。

类模板

multiset类模板定义如下:

template <class Key, class Pred = less<Key>, class B = allocator<Key> > class multiset {
    ...
};

第一个参数 Key是元素类型,第二个参数Pred是容器中元素的排序规则,可以是函数对象类也可以是函数指针类。第三个参数一般不适用。
在排序时使用Pred参数来判断大小,Pred是用 <运算符来判断的,所以元素类型应该可以进行 < 比较,即必要时重载 < 运算符。
Pred参数默认是 less,less是函数对象类模板,定义如下:

template <class_Tp>
struct less
{
    bool operator() (const _Tp &__x, const _Tp &__y) const
    { return __x < __y; }
};

less<类型>是从小到大排序,greater<类型>是从大到小排序

常用成员函数

成员函数或成员函数模板作 用
iterator find (const T & val);在容器中查找第一个值为 val 的元素,返回其迭代器。如果找不到,返 回 end()
iterator insert( const T & val);将 val 插入容器中并返回其迭代器
void insert(iterator first, iterator last);将区间 [first, last) 中的元素插人容器
int count( const T & val);统计有多少个元素的值和 val 相等
iterator lower_bound( const T & val);查找一个最大的位置 it,使得 [begin(), it) 中所有的元素者比 val 小
iterator upper_bound( const T & val);查找一个最小的位置 it,使得 [it, end()) 中所有的元素都比 val 大
pair <iterator, iterator > equal_range (const T & val);同时求得 lower_bound 和 upper_bound
iterator erase(iterator it);删除 it 指向的元素,返回其后面的元素的迭代器(Visual Studio 2010 中如此,但是在 C++ 标准和 Dev C++ 中,返回值不是这样)
iterator erase(iterator first, iterator last);删除区间 [first, last),返回 last(Visual Studio 2010 中如此,但是在 C++ 标准和 Dev C++ 中,返回值不是这样)

在比较大小时用的是 < 和 > 同时为假,而不是 ==

set

与multiset的唯一区别就是不能有重复元素
另外

insert成员函数为
pair<iterator, bool> insert(const T & val);
pair第二个参数(second)为是否插入成功,插入成功第一个参数(first)指向插入元素迭代器。没有插入成功指向原有元素迭代器。

C++中,`set` `multiset` 都属于关联容器,存储的元素都会根据元素的值自动进行排序。但两者存在以下区别: ### 元素唯一性 - `set` 容器中不允许有重复的元素,当插入重复元素时,插入操作会失败。例如以下代码: ```cpp #include <iostream> #include <set> using namespace std; void test01() { set<int> s; pair<set<int>::iterator, bool> ret = s.insert(10); if (ret.second) { cout << "第一次插入成功" << endl; } else { cout << "第一次插入失败" << endl; } ret = s.insert(10); if (ret.second) { cout << "第二次插入成功" << endl; } else { cout << "第二次插入失败" << endl; } } int main() { test01(); return 0; } ``` 该代码展示了 `set` 插入重复元素时,第二次插入会失败[^1]。 - `multiset` 容器允许有重复的元素,插入重复元素会成功。如下代码: ```cpp #include <iostream> #include <set> using namespace std; void testMultiset() { multiset<int> ms; ms.insert(10); ms.insert(10); ms.insert(10); ms.insert(10); for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++) { cout << *it << " "; } cout << endl; } int main() { testMultiset(); return 0; } ``` 该代码展示了 `multiset` 可以多次插入相同元素,且能正常存储并遍历输出[^1]。 ### 容器大小 由于 `set` 不允许重复元素,而 `multiset` 允许,所以对于包含重复元素的初始化序列,两者的大小可能不同。例如: ```cpp #include <string> #include <iostream> #include <set> #include <vector> using namespace std; int main() { vector<int> ivec; for(int i = 0; i!= 10;++i) { ivec.push_back(i); ivec.push_back(i); } set<int> iset(ivec.begin(),ivec.end()); multiset<int> miset(ivec.begin(),ivec.end()); cout << iset.size() << endl; cout << miset.size() << endl; cout << ivec.size() << endl; return 0; } ``` 此代码中,`iset` 的大小为 10,`miset` 的大小为 20,因为 `iset` 会去重,而 `miset` 保留所有元素[^2]。 ### 插入返回值 - `set` 的 `insert` 方法返回一个 `pair`,其中 `pair` 的 `second` 成员是一个布尔值,表示插入是否成功。 - `multiset` 的 `insert` 方法返回一个迭代器,指向新插入元素的位置,因为 `multiset` 插入总是成功,所以不需要返回布尔值表示插入结果。 ### 查找元素 - 在 `set` 中查找元素,若找到,返回指向该元素的迭代器;若未找到,返回 `end()` 迭代器。 - 在 `multiset` 中查找元素,若找到,返回指向该元素的迭代器;由于可能存在多个相同元素,`multiset` 还提供了 `count` 方法用于统计某个元素的出现次数。 ### 元素删除 - 在 `set` 中删除元素,若元素存在则删除并返回 1,若不存在则返回 0。 - 在 `multiset` 中删除元素,会删除所有与指定值相等的元素,并返回被删除元素的数量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值