STL08——手写一个简单版本的multiset(包含特点、原理和使用方法)、set家族总结

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;
}

set家族总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值