在vector - C ++中将带有old_value的元素替换为new_value

时间:2013-04-03 17:08:22

标签: c++ stl stdvector

我正在阅读一些遗留代码,并找到了可以改进的东西 根据设计,向量具有指向类的指针,并且所有元素在向量中都是唯一的。

函数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个元素。 < / p>

我认为,如果我使用std::replace,可以改进这一点,如{@ 3}}和MSDN documentation所述。

std :: replace 的复杂性将是old_value和new_value&amp;的O(n)比较。 1个分配操作。这很简单:

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

如果我错了,请纠正我,并就我错过的任何事情分享反馈意见 附:插入和擦除是自定义调用,它还为给定元素更新指向left_sibling和right_sibling的指针。

3 个答案:

答案 0 :(得分:2)

您甚至不需要这样做:

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

应该做的技巧 - 没有擦除,没有插入。

答案 1 :(得分:0)

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

iter = myvector->erase(i);

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

myvector->inster(iter, new_value);

或者相反。 vector insert返回指向插入元素的迭代器

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

myvector->erase(iter);

答案 2 :(得分:0)

为什么不使用其中一种?

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

为什么你有这么复杂?有什么目的吗?可能是vector也在其他地方使用,但您也可以使用以及矢量进行搜索。