Bagaimana cara membalikkan vektor C ++?

144

Apakah ada fungsi vektor bawaan di C ++ untuk membalikkan vektor pada tempatnya?

Atau apakah Anda hanya perlu melakukannya secara manual?

SirYakalot
sumber

Jawaban:

251

Ada fungsi std::reversedi algorithmheader untuk tujuan ini.

#include <vector>
#include <algorithm>

int main() {
  std::vector<int> a;
  std::reverse(a.begin(), a.end());
  return 0;
}
Ivaylo Strandjev
sumber
Bisakah Anda menjelaskan cara membalikkan vektor? Saya ingin v [0] ditukar dengan v [v.size () - 1] dan urutan v [0] [i] elemen tetap apa adanya. Ini mirip dengan mengubah urutan baris (jika vektor dipandang sebagai Matriks). Jika vektor didefinisikan sebagai: vektor <vektor <int>> v; membalikkan (v.begin (), v.end ()) tidak membalikkannya. TIA!
Vikas Goel
@VikasGoel sebenarnya cuplikan yang Anda sarankan harusnya berfungsi. Mungkin ada masalah lain?
Ivaylo Strandjev
45

Semua wadah menawarkan tampilan kontennya yang terbalik dengan rbegin()dan rend(). Kedua fungsi ini mengembalikan apa yang disebut iterator terbalik , yang dapat digunakan seperti yang normal, tetapi akan terlihat seperti wadah yang sebenarnya terbalik.

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

Contoh langsung di Ideone . Keluaran:

1->2->3->4->5
=============
5<-4<-3<-2<-1
Xeo
sumber
1
Namun itu tidak membalikkan vektor di tempat. Anda dapat membuat vektor baru dengan std :: vector <T> v2 (v1.rbegin (), v1.rend ()); v2.swap (v1); yang secara efektif akan menggunakan solusi Anda. Saya tidak melihat bagaimana itu lebih elegan atau menguntungkan dengan cara apa pun menggunakan std :: reverse.
CashCow
17
@CashCow: Ya, untuk yang pertama, ini adalah no-op, ini O (1). Membalikkan .. tidak terlalu banyak. Sebagian besar waktu, Anda tidak benar-benar membutuhkan wadah terbalik, Anda hanya perlu melihat sebagai terbalik. Bahkan, saya tidak bisa memikirkan situasi di mana Anda benar-benar membutuhkan wadah terbalik yang tidak dapat diselesaikan dengan iterator terbalik.
Xeo
4
@CashCow: Keanggunan tidak selalu benar elegan. Dalam kebanyakan kasus dalam karir profesional saya, saya hanya perlu tampilan terbalik, tetapi bukan vektor terbalik. Dan dalam semua kasus itu, kinerja akan sangat menderita jika Anda membuat lebih banyak salinan atau mengubah pemesanan. Apakah Anda juga std::sortvektor elemen 1000, jika Anda hanya perlu top-10 dalam urutan yang tidak ditentukan, karena lebih elegan daripada std::partition? Ini adalah aliran pemikiran yang melumpuhkan pengalaman PC saya hari ini seperti yang terjadi 15 tahun yang lalu, dengan perbedaan bahwa lebih banyak siklus terbuang, miliaran dari mereka.
Sebastian Mach
print_rangetidak benar: itu tidak akan berfungsi ketika rentang kosong dilewatkan.
Nawaz
jadi pertanyaan besarnya adalah, apa yang akan std::reverse(a.rbegin(), a.rend())dilakukan? ; ^)
Orwellophile
23

Anda bisa menggunakan std::reverseseperti ini

std::reverse(str.begin(), str.end());
Chuck Norris
sumber
5
Sungguh menakjubkan perbedaan yang dibuat dua menit.
jww
2

Anda juga dapat menggunakan std::listbukan std::vector. listmemiliki daftar fungsi bawaan :: membalikkan untuk membalikkan elemen.

Halo
sumber
3
std :: daftar harus lebih disukai daripada vektor dalam satu-satunya kasus memasukkan banyak elemen ke posisi sewenang-wenang dalam urutan. Menggunakan std :: list over vector hanya karena Anda akan membalik urutannya adalah ide yang buruk untuk kinerja.
eozd
0

Seringkali alasan Anda ingin membalikkan vektor adalah karena Anda mengisinya dengan mendorong semua item pada akhirnya tetapi sebenarnya menerimanya dengan urutan terbalik. Dalam hal ini Anda dapat membalikkan wadah saat Anda pergi dengan menggunakan dequegantinya dan mendorongnya langsung di depan. (Atau Anda bisa memasukkan item di depan dengan vector::insert()gantinya, tapi itu akan lambat ketika ada banyak item karena harus mengocok semua item lainnya untuk setiap penyisipan.) Jadi, berbeda dengan:

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

Anda bisa melakukannya:

std::deque<int> foo;
int nextItem;
while (getNext(nextItem)) {
    foo.push_front(nextItem);
}
// No reverse needed - already in correct order
Arthur Tacca
sumber
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
}
bashar
sumber
1
Apakah pertanyaan berusia delapan tahun ini membutuhkan jawaban duplikat lain yang tidak menambahkan apa-apa?
Blastfurnace