我有一个非常大的对象列表(节点),我希望能够根据列表中的一组值删除/删除列表中的元素。 最好是在恒定的时间......
对象(除其他外)的值如下:
long long int nodeID;
int depth;
int numberOfClusters;
double [] points;
double [][] clusters;
我需要做的是查看列表,检查除nodeID
以外的所有字段中是否有任何元素具有相同的值。
现在我正在做这样的事情:
for(i = nodes.begin(); i != nodes.end(); i++)
{
for(j = nodes.begin(); j != nodes.end(); j++)
{
if(i != j)
{
if(compareNodes((*i), (*j)))
{
j = nodes.erase (j);
}
}
}
}
其中compareNodes()
比较两个节点内的值。但这非常低效。
我正在使用erase
,因为这似乎是删除std::list
中间元素的唯一方法。
最理想的情况是,我希望能够找到基于这些值的元素,并将其从列表中删除(如果存在)。
我正在考虑某种哈希映射在常量时间内找到元素(指向元素的指针),但即使我能做到这一点,我找不到一种方法来删除元素而不迭代列表。
它似乎我必须使用erase
,但这需要遍历列表,这意味着列表大小的线性复杂性。
还有remove_if
但同样存在列表大小的线性复杂问题。
如果不迭代整个列表,是否无法从std::list
删除元素?
答案 0 :(得分:3)
首先,您可以在j
而不是std::next(i)
处开始nodes.begin()
来加快现有解决方案的速度(假设您的compareNodes
功能是可交换的)。
其次,hashmap方法听起来很可行。但是,当你可以保留迭代器时,为什么要将一个指向元素的指针保存为地图中的值?他们都是"引用元素的东西,"但您可以使用迭代器来擦除元素。并且std::list
迭代器在修改列表时不会失效(它们很可能只是引擎盖下的指针)。
第三,如果你想封装/自动化查找&顺序访问,您可以查看Boost.Multi-index以构建具有顺序和散列访问权限的容器。