在C++中使用哪种集合类型?[已关闭]

kokeuurv  于 2023-03-14  发布在  其他
关注(0)|答案(2)|浏览(157)

已关闭。此问题为opinion-based。当前不接受答案。
**想要改进此问题吗?**请更新此问题,以便editing this post可以用事实和引文来回答。

5天前关闭。
Improve this question
一个C++初学者的问题。我有一个唯一整数(1到9)的小集合。我需要能够访问该集合以:

  • 按值移除元素(集合将缩小)
  • 检查集合中是否存在值
  • 从集合中获取随机值
  • 检查集合是否为空

你会用什么?集合?无序集合?列表?向量?......我试过集合,无序集合和向量。似乎没有一个是完美的。

nwlqm0z1

nwlqm0z11#

似乎没有一个内置容器适合。
我会使用following,我有时看到它被称为“稀疏集”。

int dense[9] = {0,1,2,3,4,5,6,7,8};
int sparse[9] = {0,1,2,3,4,5,6,7,8};
int size = 0;

size是元素的个数。dense的前size个元素是集合中的数字。(注意:元素必须从0开始。如果要将1..9作为范围,请在插入到集合时减去1,在从集合阅读时加上1)。
对集合的任何操作都必须保证sparse[dense[i]] == idense[sparse[i]] == i,换句话说,sparse[i]idense中的索引,反之亦然。
要检查某个数字是否在集合中,请执行sparse[i] < size
要插入一个数字,交换dense中的两个数字,将所需的数字放在dense[size],相应地更新sparse中的索引,并递增size

// Check if the number is already in the set. If yes, abort.

int this_value = /*number to insert*/;
int this_index = sparse[this_value];
int last_index = size++;
int last_value = dense[last_index];

std::swap(dense[this_index], dense[last_index]);
std::swap(sparse[this_value], sparse[last_value]);

要删除一个数字,可以类似地交换dense中的两个数字,将所需的数字放在dense[size-1],相应地更新sparse,并递减size

// Check if the number is already not in the set. If yes, abort.

int this_value = /*number to remove*/;
int this_index = sparse[this_value];
int last_index = --size;
int last_value = dense[last_index];

std::swap(dense[this_index], dense[last_index]);
std::swap(sparse[this_value], sparse[last_value]);
eimct9ow

eimct9ow2#

一般情况

在选择容器的背后可能存在三个主要考虑因素:

*用法:容器提供我们需要的所有/大部分必需功能
*业绩:集装箱对于我们所需的操作是有效的
*便利性:该容器易于使用

以上每一个因素都可能会淘汰候选人,那么你就只能在通过这三个步骤的候选人中进行选择了。

具体案例

如果我们根据您的要求比较所有这些容器,我们可以得到:
| 集装箱|按值移除|值存在性检查|随机存取|排空检查|共计|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 标准品::列表|+|+|- -|+|第二章|
| 标准品::载体|- -|+|+|+|第二章|
| 标准::设置标准::无序设置|+|+|- -|+|第二章|
我们可以看到,这些容器都是平等的选择,只是它们没有相同的弱点。
实际上,对于std::liststd::set/std::unordered_set,您无法随机访问这些值,您需要迭代容器,直到获得所需的值。
对于std::vector,删除一个元素将导致内部数据移位(以保持它们在内存中连续,这是std::vector的要求)。

但是对于如此少量的元素(1-9),您可以忽略性能目的,只选择最方便您使用的容器,这直接将我们引向std::vector,因为它提供了使用下标运算符(operator[]())的简单随机访问。

因此,我建议您使用std::vector

相关问题