"Empty"数组\向量成员 C++

"Empty" arrayvector members c++

本文关键字:C++ 成员 向量 Empty 数组      更新时间:2023-10-16

我必须通过读取磁盘的数据来填充1000个对象的数组。但是,并非每个对象都退出。

我声明一个数组后,将保留1000个对象的内存。当我一一阅读它们时,我将内存设置为相应的值。但是,可能没有成员#276的对象,并且在声明数组时,它的内存仍将设置为所在的任何物体。

如何保留数组中某些成员无效/不存在的信息?

我可以以某种方式将成员的所有字节设置为零,但这可能是一个有效的对象。

显而易见的解决方案是添加另一个字节数组,该字节将根据该索引处的对象是否存在,但似乎并不是很优雅。

这可以用向量做到吗?它可以以某种方式存储一个空值吗?

可以用向量做到这一点吗?

no

当然,除非您使用一些额外的空间来存储该信息(是否存在),或者使用不存在的对象的前哨值。std::vector具有根据其存储的元素数量进行调整大小的强大能力。因此,如果它可以满足您的要求,它将失去这种能力。

我将使用std::unordered_map,其中每个密钥都将是对象索引(例如#276),并且该值将是实际对象。如果对象不存在,请不要在地图中插入该键。

std::map,如果您需要有效地迭代数据。在STD :: MAP和STD :: UNOREREDED_MAP。

之间选择

要么很难找到一个将您的数组的单元格标记为空的哨兵值。例如,如果您已经在内存中的某个地方将数据(尽管我认为不是您的情况),那么您可以使用一系列指针,而不是存储整个对象的数组。那么很明显,NULL指针将用于空的单元格


另一个选项是使用一对阵列,例如:std::pair<myClass, bool>,第二个操作数指示相应的单元格和不为空。

此外,您可以使用std::vector<bool>,这是非常有效的(如果您决定遵循额外数据结构的方法),那么如为什么STD :: vector&lt; bool&gt;没有.data()?但是,它将缺乏索引性能。

从逻辑上讲,您需要跟踪两个值的值,哪些值实际上将数据存储在他们。没有一个最好的方法可以做到这一点,而您做出的选择将取决于您在做什么。

在某些情况下 - 似乎您的实现不是其中之一 - 您可以保留一些特殊价值,例如nullptr-1作为前哨,并使用它来标记空插槽。您已经提到此选项在这里不存在,因此我们将排除其中一个。

另一个非常合理的选项是每个插槽是否使用该插槽是否使用该插槽,则存储并行的BitVector或某些辅助数据。如果您使用BitVector,与您对元素本身使用的内容相比,此处所需的额外内存非常小。

上述两种方法的缺点是,如果您有一个真正的巨大数组(例如,数百万个元素),您将使用大量的记忆来用于未使用的插槽,包括插槽本身和任何额外的簿记。另一个选项是使用从索引到元素键的稀疏数据结构,例如std::mapstd::unordered_map,然后仅将元素加载到实际使用的稀疏结构中。以这种方式查找单个元素的性能成本有点慢,但是记忆的收益可能很大。

首先,请确保您真的担心足够的内存以困扰优化。1000个对象不是那么多,除非它们很大,否则您希望它们稀疏。他们的索引很重要吗?也就是说,如果您加载2个对象,它们是否可以放入数组的元素0,1中,或者它们在数组中的位置很重要,并且每个对象都必须使用一个特定的数组索引?如果是这样,您可能会在数组中有大孔,并且需要指示哪些元素使用或不使用的元素(所以我不建议这样做。NULL,然后使用所使用的元素分配,并以适当的索引设置相应的指针。如果您可以压实数组,则可能还可以使用向量。

另一个选项是不要将项目放入数组中,而是像树映射一样,它仅包含您插入的元素,但仍然可以使用类似于数组索引的键找到。

(注意:std :: Unordered_map比STD :: MAP快,但是哈希表格过度分配内存(如果使用了70%的分配空间,则认为它们被认为是高度加载的),并且问题的整个目的是减少内存使用。)