ChatGPT解决这个技术问题 Extra ChatGPT

如何反转 C++ 向量?

C++ 中是否有内置的向量函数来反转向量?

还是您只需要手动完成?


L
Luc Touraille

为此目的,algorithm 标头中有一个函数 std::reverse

#include <vector>
#include <algorithm>

int main() {
  std::vector<int> a;
  std::reverse(a.begin(), a.end());
  return 0;
}

你能解释一下如何反转向量的向量吗?我希望 v[0] 与 v[v.size()-1] 交换,并且 v[0][i] 元素的顺序保持不变。这类似于更改行的顺序(如果将向量视为矩阵)。如果一个向量被定义为:vector > v; reverse(v.begin(), v.end()) 不会反转它。蒂亚!
@VikasGoel 实际上您建议的代码段应该可以工作。也许还有其他问题?
你也可以保持元素的顺序相反,然后向后迭代: for(auto i=a.end(); i!=a.begin();i--) {...} 虽然这可能很棘手一个错误。所以像其他人建议的那样使用 rbegin() 和 rend() 更好
X
Xeo

所有容器都通过 rbegin()rend() 提供其内容的反向视图。这两个函数返回所谓的reverse iterators,可以像正常使用一样,但看起来容器实际上是反转的。

#include <vector>
#include <iostream>

template<class InIt>
void print_range(InIt first, InIt last, char const* delim = "\n"){
  --last;
  for(; first != last; ++first){
    std::cout << *first << delim;
  }
  std::cout << *first;
}

int main(){
  int a[] = { 1, 2, 3, 4, 5 };
  std::vector<int> v(a, a+5);
  print_range(v.begin(), v.end(), "->");
  std::cout << "\n=============\n";
  print_range(v.rbegin(), v.rend(), "<-");
}

Live example on Ideone。输出:

1->2->3->4->5
=============
5<-4<-3<-2<-1

然而,这并没有就地反转向量。您可以使用 std::vector v2( v1.rbegin(), v1.rend() ); 创建一个新向量v2.swap(v1);这将有效地使用您的解决方案。不过,我看不出使用 std::reverse 以任何方式更优雅或更有利。
@CashCow:嗯,首先,这是一个无操作,它是 O(1)。倒车。。没那么多。大多数时候,你并不需要一个反转的容器,你只需要看到它是反转的。事实上,我想不出你真正需要一个无法用反向迭代器解决的反向容器的情况。
@CashCow:优雅并不总是真正的优雅。在我职业生涯的大多数情况下,我只需要一个反向视图,而不是一个反向向量。在所有这些情况下,如果您创建更多副本或转换顺序,性能将完全不必要地受到影响。如果您只需要未指定顺序的前 10 个元素,您是否还会 std::sort 一个 1000 元素向量,因为它比 std::partition 更优雅?就像 15 年前一样,这是一种思想流派,它削弱了我今天的 PC 体验,不同之处在于浪费了更多的周期,数十亿个周期。
print_range 不正确:超过 empty 范围时它将不起作用。
所以最大的问题是,std::reverse(a.rbegin(), a.rend()) 会做什么? ;^)
C
Chuck Norris

您可以像这样使用 std::reverse

std::reverse(str.begin(), str.end());

A
Arthur Tacca

通常,您想要反转向量的原因是因为您通过在最后推动所有项目来填充它,但实际上是以相反的顺序接收它们。在这种情况下,您可以通过使用 deque 来反转容器并将它们直接推到前面。 (或者您可以使用 vector::insert() 在前面插入项目,但是当有很多项目时,这会很慢,因为每次插入都必须将所有其他项目随机排列。)而不是:

std::vector<int> foo;
int nextItem;
while (getNext(nextItem)) {
    foo.push_back(nextItem);
}
std::reverse(foo.begin(), foo.end());

您可以改为:

std::deque<int> foo;
int nextItem;
while (getNext(nextItem)) {
    foo.push_front(nextItem);
}
// No reverse needed - already in correct order

缺点是元素在内存中不再像向量一样连续,所以你不能使用 .data()
A
Ajay

您也可以使用 std::list 代替 std::vectorlist 具有用于反转元素的内置函数 list::reverse


在将许多元素插入序列中的任意位置的唯一特定情况下,std::list 应该优于 vector 。在向量上使用 std::list 只是因为您将反转序列在性能方面是一个坏主意。