Bir C ++ vektörünü nasıl tersine çeviririm?


148

C ++ 'da bir vektörü yerinde ters çevirmek için yerleşik bir vektör işlevi var mı?

Yoksa sadece manuel olarak mı yapmanız gerekiyor?

Yanıtlar:


260

Bir işlev var std::reverseiçinde algorithmbu amaçla başlığındaki.

#include <vector>
#include <algorithm>

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

Vektörlerin vektörünü nasıl tersine çevireceğinizi açıklayabilir misiniz? V [0] 'ın v [v.size () - 1] ile yer değiştirmesini ve v [0] [i] öğesinin sırasının olduğu gibi kalmasını istiyorum. Bu, satırların sırasını değiştirmeye benzer (bir vektör Matris olarak görülüyorsa). Bir vektör şu şekilde tanımlanırsa: vektör <vektör <int>> v; reverse (v.begin (), v.end ()) bunu tersine çevirmez. TIA!
Vikas Goel

@VikasGoel aslında önerdiğiniz snippet çalışmalıdır. Belki başka bir sorun vardır?
Ivaylo Strandjev

45

Tüm kaplar , içeriklerinin ve ile ters bir görünümünü sunar . Bu iki işlev, sözde ters yineleyiciler döndürür , bunlar normal işlevler gibi kullanılabilir, ancak kap aslında tersine çevrilmiş gibi görünecektir.rbegin()rend()

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

Ideone'da canlı örnek . Çıktı:

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

1
ancak bu, vektörü yerinde tersine çevirmez. Std :: vector <T> v2 (v1.rbegin (), v1.rend ()); ile yeni bir vektör oluşturabilirsiniz; v2.swap (v1); çözümünüzü etkili bir şekilde kullanır. Yine de std :: reverse kullanmanın nasıl daha zarif veya daha avantajlı olduğunu görmüyorum.
CashCow

17
@CashCow: Birincisi, bu bir işlem değil, O (1). Geri dönüyor ... o kadar değil. Çoğu zaman, gerçekten ters çevrilmiş bir konteynere ihtiyacınız yoktur, sadece onu tersine çevrilmiş olarak görmeniz gerekir. Aslında, ters yineleyicilerle çözülemeyen ters çevrilmiş bir konteynere gerçekten ihtiyaç duyduğunuz bir durumu düşünemiyorum.
Xeo

4
@CashCow: Zarafet her zaman gerçek zarafet değildir. Profesyonel kariyerimdeki çoğu durumda, sadece ters bir bakış açısına ihtiyacım vardı, ancak ters bir vektöre ihtiyacım yoktu. Ve tüm bu durumlarda, daha fazla kopya oluşturursanız veya sıralamayı dönüştürürseniz performans tamamen gereksiz yere zarar görür. Ayrıca misiniz std::sort1000 eleman vektör, bu daha şık olduğu için sadece, top-10 belirtilmemiş sırayla gerekirse std::partition? Bu, milyarlarca döngünün boşa gitmesi farkıyla, 15 yıl önce olduğu gibi bugün de benim PC deneyimimi sakat bırakan düşünce okulu.
Sebastian Mach

print_rangedoğru değil: boş aralık geçildiğinde çalışmayacaktır.
Nawaz

Öyleyse büyük soru, ne yapacak std::reverse(a.rbegin(), a.rend())? ; ^)
Orwellophile

24

Sen kullanabilirsiniz std::reverseBöyle

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

8
İki dakikanın yarattığı fark inanılmaz.
jww

2

Bunun std::listyerine de kullanabilirsiniz std::vector. listyerleşik bir fonksiyon listesine sahiptir :: ters elemanlar için ters.


3
Sıradaki rastgele konumlara çok sayıda eleman eklemenin tek özel durumunda std :: list vektör yerine tercih edilmelidir. Sırf diziyi ters çevireceğiniz için vektör yerine std :: list kullanmak performans açısından kötü bir fikirdir.
eozd

0

Çoğu zaman vektörü tersine çevirmek istemenizin nedeni, sonunda tüm öğeleri iterek doldurmanız, ancak aslında onları ters sırada alıyor olmanızdır. Bu durumda, konteyneri ilerledikçe dequebunun yerine a kullanarak ve doğrudan öne iterek ters çevirebilirsiniz . (Veya vector::insert()bunun yerine öğeleri ön tarafa yerleştirebilirsiniz , ancak bu, her ekleme için diğer tüm öğeleri karıştırması gerektiğinden çok sayıda öğe olduğunda yavaş olacaktır.)

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

Bunun yerine şunları yapabilirsiniz:

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
}

2
Bu sekiz yaşındaki soru, hiçbir şey eklemeyen başka bir yinelenen yanıta mı ihtiyaç duyuyor?
Blastfurnace
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.