在std ::对象列表中快速搜索和删除

时间:2015-02-20 09:32:44

标签: c++ list stdlist

我有一个非常大的对象列表(节点),我希望能够根据列表中的一组值删除/删除列表中的元素。 最好是在恒定的时间......

对象(除其他外)的值如下:

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删除元素?

1 个答案:

答案 0 :(得分:3)

首先,您可以在j而不是std::next(i)处开始nodes.begin()来加快现有解决方案的速度(假设您的compareNodes功能是可交换的)。

其次,hashmap方法听起来很可行。但是,当你可以保留迭代器时,为什么要将一个指向元素的指针保存为地图中的值?他们都是"引用元素的东西,"但您可以使用迭代器来擦除元素。并且std::list迭代器在修改列表时不会失效(它们很可能只是引擎盖下的指针)。

第三,如果你想封装/自动化查找&顺序访问,您可以查看Boost.Multi-index以构建具有顺序和散列访问权限的容器。