【问题标题】:Replace an element with old_value to new_value in vector - C++用 old_value 将元素替换为向量中的 new_value - C++
【发布时间】:2013-04-03 17:08:21
【问题描述】:

我正在查看一些遗留代码,并发现了一些可以改进的地方。
根据设计,向量具有指向类的指针,并且向量中的所有元素都是唯一的。

ReplaceVal 函数将向量中具有 old_value 的元素替换为 new_value,方式如下:

iterator i, i_e;
i   = vector->begin();
i_e = vector->end ();
for (; i != i_e; ++i)
{
    if ((*i) == old_child)
        break;
}
// Insertion
    vector->insert_call(new_child, i);

// Since, the pointers are invalidated, do another find for erase
    i   = vector->begin();
    i_e = vector->end ();
    for (; i != i_e; ++i)
    {
        if ((*i) == old_child)
            break;
    }
// Finally, erase the old_value
    vector->erase_call(i);

因此,本质上,这涉及元素移动两次每次插入和擦除,如果您要在矢量中间插入和擦除元素。
对于 n 次插入和删除调用复杂度为 O(n*m)如果平均每次移动 m 个元素。

我认为,如果我使用std::replace,这可以改进,正如这里提到的@MSDN documentationstd_replace_example

std::replace 的复杂性是 O(n) old_value 和 new_value & 1 赋值操作的比较。很简单:

replace (vector.begin( ), vector.end( ), old_value , new_value);

如果我错了,请纠正我,并就我遗漏的任何内容分享反馈。
附:插入和擦除是自定义调用,它们还会更新给定元素的指向 left_sibling 和 right_sibling 的指针。

【问题讨论】:

标签: c++ stl stdvector


【解决方案1】:

你甚至不需要这样做:

iterator position = std::find( vector->begin() vector->end(), old_child );
if ( position == vector->end() ) {
    throw NoSuchElement();
}
*position = new_child;

应该可以解决问题——不擦除也不插入。

【讨论】:

  • 非常感谢。我没有考虑简单的方法,而是跳到 std::replace。
  • 如果元素不存在,或者它多次出现,则 this 和 replace 的语义是不同的。 (要获得原始代码的确切语义,如果未找到该元素,您应该追加而不是抛出异常。如果 old_child == new_child 可能会做一些特殊的事情。)
  • 谢谢伙计。但这种情况已经得到处理。我已经对情况进行了简化视图以获得快速答案。
【解决方案2】:

向量擦除返回一个迭代器,指向被擦除后元素的位置

iter = myvector->erase(i);

然后你可以使用那个迭代器来插入。

myvector->inster(iter, new_value);

或者反过来。 vector insert 返回一个指向插入元素的迭代器

iter = myvector->inster(i, new_value);

myvector->erase(iter);

【讨论】:

    【解决方案3】:

    为什么不使用其中之一?

    • std::set
    • std::multiset
    • std::unordered_set
    • std::unordered_multiset

    为什么你有这样的复杂性?有没有什么目的。可能vector 也在其他地方使用,但您也可以使用 sets 和向量进行搜索。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-16
      • 2011-10-07
      • 1970-01-01
      • 1970-01-01
      • 2018-07-23
      • 2014-11-20
      • 2017-02-27
      • 1970-01-01
      相关资源
      最近更新 更多