Làm cách nào để đảo ngược một vectơ C ++?


144

Có một hàm vectơ tích hợp trong C ++ để đảo ngược một vectơ tại chỗ không?

Hay bạn chỉ phải làm bằng tay?

Câu trả lời:


251

Có một chức năng std::reversetrong algorithmtiêu đề cho mục đích này.

#include <vector>
#include <algorithm>

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

Bạn có thể giải thích làm thế nào để đảo ngược vectơ? Tôi muốn v [0] được hoán đổi với v [v.size () - 1] và thứ tự của phần tử v [0] [i] vẫn như cũ. Điều này tương tự với việc thay đổi thứ tự các hàng (nếu một vectơ được xem dưới dạng Ma trận). Nếu một vectơ được định nghĩa là: vectơ <vector <int >> v; đảo ngược (v.begin (), v.end ()) không đảo ngược nó. TIA!
Vikas Goel

@VikasGoel trên thực tế đoạn trích bạn đề xuất nên hoạt động. Có lẽ có một số vấn đề khác?
Ivaylo Strandjev

45

Tất cả các container cung cấp một cái nhìn đảo ngược về nội dung của họ với rbegin()rend(). Hai hàm này trả về các lệnh gọi ngược lại , có thể được sử dụng như các hàm bình thường, nhưng nó sẽ trông giống như container thực sự bị đảo ngược.

#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(), "<-");
}

Ví dụ trực tiếp trên Ideone . Đầu ra:

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

1
tuy nhiên điều đó không đảo ngược véc tơ tại chỗ. Bạn có thể tạo một vectơ mới với std :: vector <T> v2 (v1.rbegin (), v1.rend ()); v2.swap (v1); mà sẽ sử dụng hiệu quả giải pháp của bạn. Tôi không thấy làm thế nào nó thanh lịch hoặc thuận lợi hơn trong bất kỳ cách nào để sử dụng std :: Reverse mặc dù.
CashCow

17
@CashCow: Chà, đối với một người, đó là không có, đó là O (1). Đảo ngược .. không quá nhiều. Hầu hết thời gian, bạn không thực sự cần một container đảo ngược, bạn chỉ cần xem nó là đảo ngược. Trong thực tế, tôi không thể nghĩ đến một tình huống mà bạn thực sự cần một container ngược mà không thể giải quyết bằng các trình vòng lặp ngược.
Xèo

4
@CashCow: Sự thanh lịch không phải lúc nào cũng là sự thanh lịch thực sự. Trong hầu hết các trường hợp trong sự nghiệp chuyên nghiệp của tôi, tôi chỉ cần một cái nhìn đảo ngược, nhưng không phải là một vectơ đảo ngược. Và trong tất cả các trường hợp đó, hiệu suất sẽ hoàn toàn không cần thiết nếu bạn tạo thêm bản sao hoặc chuyển đổi thứ tự. Bạn cũng sẽ có std::sortmột vectơ 1000 phần tử, nếu bạn chỉ cần top 10 theo thứ tự không xác định, bởi vì nó thanh lịch hơn std::partition? Đây là trường phái cho rằng làm tê liệt trải nghiệm PC của tôi ngày hôm nay như cách đây 15 năm, với sự khác biệt là còn nhiều chu kỳ bị lãng phí, hàng tỷ người trong số họ.
Sebastian Mach

print_rangelà không chính xác: nó sẽ không hoạt động khi phạm vi trống được thông qua.
Nawaz

Vì vậy, câu hỏi lớn là, những gì sẽ std::reverse(a.rbegin(), a.rend())làm gì? ; ^)
Orwellophile

23

Bạn có thể sử dụng std::reversenhư thế này

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

5
Thật đáng kinh ngạc sự khác biệt hai phút làm cho.
jww

2

Bạn cũng có thể sử dụng std::listthay vì std::vector. listcó một danh sách chức năng tích hợp :: đảo ngược để đảo ngược các phần tử.


3
std :: list nên được ưu tiên hơn vector trong trường hợp cụ thể duy nhất là chèn nhiều phần tử vào các vị trí tùy ý trong chuỗi. Sử dụng std :: list trên vector chỉ vì bạn sẽ đảo ngược trình tự là một ý tưởng tồi về hiệu năng.
eozd

0

Thông thường lý do bạn muốn đảo ngược vectơ là vì bạn điền nó bằng cách đẩy tất cả các mục vào cuối nhưng thực sự nhận được chúng theo thứ tự ngược lại. Trong trường hợp đó, bạn có thể đảo ngược container khi bạn đi bằng cách sử dụng dequethay thế và đẩy chúng trực tiếp lên mặt trước. (Hoặc bạn có thể chèn các mục ở phía trước vector::insert()thay vào đó, nhưng điều đó sẽ chậm khi có nhiều mục vì nó phải xáo trộn tất cả các mục khác cho mỗi lần chèn.) Vì vậy, trái ngược với:

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

Thay vào đó, bạn có thể làm:

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

0
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
int main()
{
    vector<int>v1;
    for(int i=0; i<5; i++)
        v1.push_back(i*2);
    for(int i=0; i<v1.size(); i++)
        cout<<v1[i];    //02468
    reverse(v1.begin(),v1.end());
    
    for(int i=0; i<v1.size(); i++)
        cout<<v1[i];   //86420
}

1
Có phải câu hỏi tám tuổi này cần một câu trả lời trùng lặp khác mà không thêm gì không?
Blastfurnace
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.