更新排序向量的一个条目

时间:2019-04-21 22:45:57

标签: c++ sorting

假设我有一个名为std::vector<int>的已排序v。我增加了v[i]的值,并且想对向量进行重新排序。假设我希望仅将v[i]增加一点。以下肯定是错误的。

// (WRONG)
int x = v[i]; // the new v[i], that is
v.erase(v.begin() + i);
v.insert(
    std::upper_bound(v.begin() + i, v.end(), x),
    x
);

这是错误的,因为删除时我几乎将整个数组移回,插入时又将其向前移动,而我可能只需要稍微增加v[i],这只需要移动几个条目即可。另一个想法可能是:

int x = v[i]; // the new v[i], that is
if (/* new v[i] is > old v[i] */) {
    size_t j = i + 1;
    while (v[j] < x && j < v.size()) {
        std::swap(v[j-1], v[j])
        j++;
    }
}

,如果我减少v[i]而不是增加它,则类似。这是最好的吗?

假设我无权访问boost::flat_set。 (不确定是否可以轻松地做到这一点。)如果已回答,则表示歉意。搜索没有找到答案。

2 个答案:

答案 0 :(得分:3)

使用std::rotate将元素移动到新位置。如果您确实认为它不会走太远,则线性搜索新位置可能会更快(或通过检查距旧位置两倍的距离以找到upper_bound的边界来应用混合方法)。

答案 1 :(得分:2)

在不需要时,您不应该先erase然后再insert个元素。如果您在迭代器pos处增加元素,则只需找到插入元素并将元素旋转一个的位置:

 auto new_pos = std::lower_bound(pos,end,*pos);
 std::rotate(pos,pos+1,new_pos);