【问题标题】:optimization: vector.erase() of pointer优化:指针的vector.erase()
【发布时间】:2021-04-14 12:53:29
【问题描述】:

我有一个关于删除指针和优化的动态向量的问题。

这是我的代码。它检查一个元素是否必须设置为 nullptr,然后删除所有这些元素。

for (auto* el : elements)
    {
        if (el != 0)
            // do something
        else
            el = nullptr;
    }
    elements.erase(std::remove(elements.begin(), elements.end(), nullptr), elements.end());

这个操作的复杂性对机器来说是否繁重? 如果是这样,那么有没有更好的方法来做到这一点并且值得吗?因为,在这里,索引顺序的保存对我来说并不重要。

谢谢!

【问题讨论】:

    标签: pointers optimization vector erase


    【解决方案1】:

    这个操作的复杂性对机器来说是否繁重?

    有点费钱,不过比之前的操作贵不了多少。实际上,remove 通常会检查每个项目的值,如果需要删除某个项目,算法会将右边的项目移动到当前分析的项目上。 erase 通常相对便宜,因为它只是调整向量的大小以在最后跳过剩余的垃圾(通常没有任何复制或重新分配)并调用丢弃项目的析构函数(仅当它们很多且析构函数时成本高是不平凡的)。此操作可能与前一个操作一样昂贵

    如果是,那么是否有更好的方法并且值得?因为,在这里,索引顺序的保存对我来说并不重要。

    是的,这是可能的:您可以使用经典循环遍历数组,然后交换当前项与末尾的一项以丢弃它。您需要维护一个从末尾移动到开头的 end 迭代器。当到达结束迭代器时,循环停止。请注意,您的谓词也应检查来自末尾的交换项目。

    或者,您可以只使用 std::partition,该算法的作用非常相似,而且更简单:它将验证给定条件的项目放在左侧,将另一个放在右侧部分。然后,您可以调整数组的大小以删除不需要的右侧部分。

    std::partition 应该比其他基于交换的方法效率低一些,因为它必须保持双方的一致性。

    这是std::partition 的(未经测试的)示例:

    auto discardedBegin = partition(elements.begin(), elements.end(), doSomething);
    elements.erase(discardedBegin, elements.end());
    

    【讨论】:

      猜你喜欢
      • 2020-05-08
      • 1970-01-01
      • 2018-12-24
      • 2011-05-18
      • 1970-01-01
      • 2014-09-08
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      相关资源
      最近更新 更多