在向量的开始处添加向量本身的最后两个元素,并在向量的末尾添加向量的前两个元素,这是最智能的方法吗? 我的意思是,如果我的起始载体是
v = 1 2 3 4 5 6 7 8 9
我需要它成为
v = 8 9 1 2 3 4 5 6 7 8 9 1 2
答案 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());
击> <击> 撞击>编辑: 是未定义的行为。