STL08——手写一个简单版本的multiset(包含特点、原理和使用方法)
1.特点
-
有序性:
multiset
中的元素是有序的且按照元素的值进行升序排序,因此在 multiset 中的元素可以很方便地进行有序访问。 -
允许重复元素: 与
set
不同,multiset
允许存储相同的元素多次,并且它们在排序后会依然保持有序。 -
基于红黑树实现
2.使用方法
#include <set>
multiset<int> myMultiset
- 使用场景:有序存储允许重复元素的场景
3.原理(计数器)
在 multiset 中,为了存储重复元素,红黑树的每个节点都包含一个键和一个计数器,用于表示该键在 multiset 中的出现次数。
手写一个简单版本的multiset
【STL 专题之 multiset】multiset 的实现
题目描述
本题需要设计一个 multiset 类,实现如下功能:
1、基础功能
- 构造函数:初始化 multiset 实例
- 析构函数:清理资源,确保无内存泄露
2、核心功能
- 在 multiset 中插入一个元素
- 在 multiset 中删除元素
- 判断一个元素是否在 multiset 中
- 判断 multiset 是否为空
- 获取 multiset 的大小
输入描述
题目的包含多行输入,第一行为正整数 N, 代表后续有 N 行命令序列。
接下来 N 行,每行包含一个命令,命令格式为 [operation] [parameters] ,具体命令如下:
insert 命令:
- 格式:insert [element]
- 功能:在 multiset 中添加 element,如果元素已经存在,则不进行任何操作
erase 命令:
- 格式:erase [element]
- 功能:删除 multiset 中的所有 element ,如果 element 不存在,则不进行任何操作
count 命令:
- 格式:count [element]
- 功能:查询 multiset 中 element 的数量
empty 命令:
- 格式:empty
- 功能:判断 multiset 是否为空
size 命令:
- 格式:size
- 功能:获取 multiset 的大小
输出描述
输出为每行命令执行后的结果,具体输出格式如下:
insert 命令:无输出
erase 命令:无输出
count 命令:输出一个整数,独占一行,代表 multiset 中该元素的数量
empty 命令:如果 multiset 为空,则输出 true,否则输出 false
size 命令:输出一个整数,独占一行,表示 multiset 中所有元素的数量
#include"RedBlackTree.h"
#include <cstddef>
#include <stdexcept>
template<typename Key>
class MultiSet
{
private:
RedBlackTree<Key, size_t> rbTree;
size_t sz;
public:
MultiSet():sz(0)
{}
~MultiSet()
{}
void insert(const Key& key)
{
auto it = rbTree.at(key);
if (it != NULL)
{
(*it)++;//*it的值就是value,而不是key
sz++;
}
else
{
rbTree.insert(key, 1);
sz++;
}
}
void erase(const Key& key)
{
auto it = rbTree.at(key);
if (it != NULL)
{
(*it)--;
sz--;
if (*it == 0)
rbTree.remove(key);
}
}
size_t size() const { return sz; }
bool empty() const { return sz == 0; }
size_t count(const Key& key)
{
auto it = rbTree.at(key);
if (it != NULL)
return *it;
else
return 0;
}
void clear() {
sz = 0;
rbTree.clear();
}
};
int main() {
MultiSet<int> mySet;
int N;
std::cin >> N;
getchar();
std::string line;
for (int i = 0; i < N; i++) {
std::getline(std::cin, line);
std::istringstream iss(line);
std::string command;
iss >> command;
int element;
if (command == "insert") {
iss >> element;
mySet.insert(element);
}
if (command == "erase") {
iss >> element;
mySet.erase(element);
}
if (command == "count") {
iss >> element;
std::cout << mySet.count(element) << std::endl;
}
if (command == "size") {
std::cout << mySet.size() << std::endl;
}
if (command == "empty") {
std::cout << (mySet.empty() ? "true" : "false") << std::endl;
}
}
return 0;
}