2011-12-09 17 views
5

bir vectorpair<int,int> olduğunu farz sağlar. Şimdi pair.first ve pair.second'u bağımsız vektörler olarak çıkarmak istiyorum. Ben vektör üzerinde yineleyebilir ve yapabilirim ama daha iyi/daha hızlı bir yol var mı?hızlı yolu ++

+0

Ben vektör tüm maddelerin üzerindedir döngü daha hızlı yapma herhangi bir yol göremiyorum. Yine de, döngü yapmak zorunda değilsiniz, ['std :: for_each'] gibi bir şey kullanın (http://en.cppreference.com/w/cpp/algorithm/for_each). –

+0

Değerleri yeni vektörlere kopyalamanız gerektiğinden emin misiniz? Belki de kopyalamaksızın çift öğeleri alırken orijinal vektör üzerinde yinelemek için [transform_iterators] (http://www.boost.org/doc/libs/release/libs/iterator/doc/transform_iterator.html) kullanabilirsiniz. başka yerde. –

+0

evet. ama destek kullanmak istemedim. Her neyse, herkes doğru cevabı verdiler, böylece cevabı en iyi 'detaylar' ile kabul ediyorum. – Neal

cevap

11

artık eski vektör gerekmiyorsa, belki hareket semantik ekstra verimlilik bir nebze alabilir, 11 ++ bir döngüden daha iyi. Her öğeye en az bir kez dokunmanız gerekecek, yani bu kadar verimli olacak. eleman tipleri kendilerini kopyalama daha iyidir hareket anlambilim varsa hareketli sadece bir fark yaratabilir

Not. Bu, int s veya herhangi bir POD için geçerli değildir. Ancak kodunuzu genel olarak yazmak zahmete giremez, böylece gelecekteki durumlarda bundan faydalanabilirsiniz. kopyalama/hareketli bir sorun varsa

olsa da, orijinal vektör için bazı görüş adaptörü, daha iyi bir yaklaşım olabilir değerlendirmelidir.

+1

Whoa, make_move_iterator', +1 –

+0

@SethCarnegie hakkında bir şey bilmiyordu: Aslında burada bunun gerekli olduğundan şüphe duyuyorum; Ben sadece eğlenmek için koydum ('std :: move' zaten hile yapmalı). Hareket yineleyici, algoritmalar için çok yararlı olsa da. Std :: copy''in hareketli sürümü olan ['algorithm/std :: move'] (http://en.cppreference.com/w/cpp/algorithm/move) adresinde önceden gelir. –

+0

@KerrekSB: Ve * ekstra verimlilik * ne olacak? Bunun daha idiyomik düz döngüden daha verimli olacağını sanmıyorum - aynı zamanda akılda tutulması daha kolaydır. –

3

Hayır yok. Dikkat edilmesi gereken tek şey, gereksiz yeniden tahsisleri önlemek için ortaya çıkan iki vektör üzerinde reserve'u kullanmaktır.

1

Sen Karmaşıklık açısından, bu alabilirsiniz kadar iyidir, böylece yine vektörü üzerinde yineleme yapmak zorunda.

daha
for (auto it = std::make_move_iterator(v.begin()), 
     end = std::make_move_iterator(v.end()); it != end; ++it) 
{ 
    v1.push_back(std::move(it->first)); 
    v2.push_back(std::move(it->second)); 
} 

Diğer, kesinlikle yapamaz: C

2

Sen yinelemeyi önlemek mümkün olmayacaktır. En hızlı çözüme gelince, , bu çiftte ne olduğuna ve gerçek uygulamaya bağlıdır. Bunlara bağlı olarak, hedef vektörleri ile doğru boyutta oluşturmak ve bunlara atamak daha iyi olabilir; veya bunları boş oluşturmak ve reserve ve sonra push_back kullanın. Ayrıca, indekslemeyi yineleyicileri kullanarak karşılaştırmak isteyebilirsiniz; Ön boyutlu vektörler kullanıyorsanız, üç yerine yalnızca bir kontrol değişkenini kullanarak bir iyileştirme olabilir. (G ++ Doğru boyutta vektörler ve belirlenmesini oluşturma, ölçülen son ile olduğu dahili olarak iki döngü anlamına ve değerleri başlatılıyor rağmen., En az double için, reserve ve push_back kullanarak daha hızlı 0.0.)

Ayrıca() zaten bunları yok varsayarak çiftinin birinci ve ikinci elemanları ayıklamak için işlevsel nesneler oluşturmayı deneyin ve transform iki çağrı kullanmak isteyebilirsiniz. Yine, ya bir önceden belirlenmiş vektör ile ya da hedef olarak bir arka yerleştirici kullanarak. Kapalı el, ben , bunun daha iyi bir performans göstermesini beklemez, ama asla bilemezsiniz.