在向量的开头和结尾添加

时间:2014-01-30 23:23:56

标签: c++ vector

在向量的开始处添加向量本身的最后两个元素,并在向量的末尾添加向量的前两个元素,这是最智能的方法吗? 我的意思是,如果我的起始载体是

v = 1 2 3 4 5 6 7 8 9

我需要它成为

v = 8 9 1 2 3 4 5 6 7 8 9 1 2

3 个答案:

答案 0 :(得分:4)

首先,如果容器变大,请考虑使用deque而不是vector。在开始时添加它会更有效。

对于vector,你不能将vector之外的元素插入到开头,因为发生的第一件事是向量中的所有内容都被移动(并且所有迭代器和对这些元素的引用都无效) )。因此,您需要从向量中复制元素,或者需要在开头放置插入元素,然后复制 - 赋值给它们。假设类型为int,我会选择前者:

if (v.size() >= 2) {
    int tmp[] = {*(v.end() - 2), *(v.end() - 1)};
    v.insert(v.begin(), tmp, tmp + 2);
    tmp[0] = v[2]; tmp[1] = v[3];
    v.insert(v.end(), tmp, tmp + 2);
}

或者,这会占用更多内存,但可能更容易阅读。作为奖励,即使对于复制构造函数可以抛出的类型,它也提供了强大的异常保证。我上面的代码可以通过添加对reserve的调用来提供强有力的保证,但只是因为int是一个微不足道的类型:

if (v.size() >= 2) {
    std::vector<int> new_v;
    new_v.reserve(v.size() + 4);
    new_v.insert(new_v.end(), v.end() - 2, v.end());
    new_v.insert(new_v.end(), v.begin(), v.end());
    new_v.insert(new_v.end(), v.begin(), v.begin() + 2);
    v.swap(new_v);
}

对于deque,如果使用引用而不是迭代器来访问容器,则不需要在容器外部存储任何元素。同样,这只提供了基本的例外保证。

if (v.size() >= 2) {
    v.push_front(v.back());
    v.push_front(*&(v.end() - 1));
    v.push_back(*&(v.begin() + 2));
    v.push_back(*&(v.begin() + 3));
}

答案 1 :(得分:2)

我的五美分

    std::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    v.insert( v.end(), { v[0], v[1], v[v.size() - 2], v[v.size() - 1] } );
    std::rotate( v.begin(), std::prev( v.end(), 2 ), v.end() );

    for ( int x : v ) std::cout << x << ' ';
    std::cout << std::endl;

答案 2 :(得分:0)

通过对范围使用vector :: insert函数。首先在末尾插入前两个元素会更容易。

v.insert(v.end(), v.begin(), v.begin()+2);
v.insert(v.begin(), v.end()-2, v.end());

<击> 编辑: 是未定义的行为。

Appending std::vector to itself, undefined behavior?