我不确定重组这个词是否是正确的术语,但它是我描述我正在寻找的唯一方法。
如果我有一系列的说法,猫,就像这样:
CAT *myCats[99];
myCats[0] = new CAT;
myCats[1] = new CAT;
myCats[2] = new CAT;
myCats[3] = new CAT;
myCats[4] = new CAT;
myCats[5] = new CAT;
在某个时间点,我们可以说myCats [3]被删除了:
delete myCats[3];
现在我有以下内容:
myCats[0]
myCats[1]
myCats[2]
myCats[4]
myCats[5]
是否有一种简单的方法来重新组织阵列,使其移动4-> 3和5-> 4,基本上填补空白?
myCats[0]
myCats[1]
myCats[2]
myCats[3]
myCats[4]
是实现这一目标的最佳方法,基本上遍历数组并确定如果元素为空/缺失,我只需将下一个现有元素移动到其位置?我该怎么做?如何确定阵列中任何点的Cat元素是否存在?还是有一种更简单的预先确定的方法来完成我需要的东西?
很抱歉,如果示例和语法有点偏差。我是C ++的新手。
更新
感谢您的快速建议。看起来像Vector是要走的路。我总是忘记矢量。在我的脑海中,Vector只是一个容纳x,y和z值的容器: - )
答案 0 :(得分:14)
如果您使用的是C ++,则可以使用std::vector
:
std::vector<CAT*> cats;
cats.push_back(new CAT);
cats.push_back(new CAT);
cats.push_back(new CAT);
// remove the second cat
delete cats[1];
cats.erase(cats.begin() + 1);
现在,载体中有两只猫(插入的第一只和第三只猫),它们的指数为零和一。
但是,在C ++中,没有理由动态分配所有内容,所以只用vector<CAT>
就可能会更好:
std::vector<CAT> cats;
cats.push_back(CAT());
cats.push_back(CAT());
cats.push_back(CAT());
// remove the second cat
cats.erase(cats.begin() + 1);
通过这种方式,可以自动处理猫的破坏,您不必担心自己管理任何内存。
如果你做必须使用指针(例如,你的类是多态基类),你可能想要使用std::vector
智能指针(例如,{{ 1}}为s)。使用智能指针,您不必记住在完成对象后删除它们 - 它会自动完成。例如,使用shared_ptr
的上述代码如下所示:
shared_ptr
(您的标准库可能尚未在std::vector<std::shared_ptr<CAT> > cats;
cats.push_back(std::make_shared(new CAT));
cats.push_back(std::make_shared(new CAT));
cats.push_back(std::make_shared(new CAT));
// remove the second cat
// note we don't need to call delete; shared_ptr does that for us
cats.erase(cats.begin() + 1);
命名空间中包含shared_ptr
;在这种情况下,you may find it elsewhere)。如果您不熟悉std
,the Boost documentation会有很好的介绍。
答案 1 :(得分:3)
正如其他人已经指出的那样使用std :: vector会为你做所有的重新分配,但它仍然是一个O(n)操作。但是,您可以使用其他数据结构做得更好。例如std :: list允许您从O(1)中的列表中的任何位置删除元素。
最终哪种数据结构最合适将取决于您需要支持的所有操作,它们的相对频率以及每种操作所需的性能。
答案 2 :(得分:1)
您可以在删除后将NULL
指定给指针,然后检查指针是否为NULL或保留一个相同大小的bool数组,以指示该对象是否存在。至于重组:如果顺序很重要,那么你必须按照描述移动所有元素。如果订单无关紧要,只需将最后一个元素移到缺失的空白处即可。
答案 3 :(得分:1)
您是否有任何特定原因无法使用std::vector而不是数组? Vector会自动调整大小,因此您不必担心这一点。