2016-01-25 24 views
6

unordered_set öğesinin sırasız öğelerin çiftlerini yinelemenin kısa bir yolu nedir?Bir unordered_set içindeki sırasız çiftler nasıl yinelenir?

(Yani sırası önemli değildir ve elementler farklı olmalı)

örn

for (i = 0; i < size - 1; i++) { 
    for (j = i + 1; j < size; j++) { 
    ... 
    } 
} 

gibi {1, 2, 3} => (1, 2) (2, 3) (1, 3)

Benim ilk girişimleri vardı bir şey Ama bununla süper uygun değil yineleyiciler. Verilen

+3

@arainone Olası 'Ben soruyu okumadım' durumu. – orlp

+0

Yani bir dizi 'X' istediğiniz küme için {(x1, x2) | x1, x2 ∈ X, x1 \t ≠ x2} '? Bunu doğru okudum mu? –

+0

Üst üste geldiğinde ('[0,1], [1,2] [2,3] ...') veya istersiniz [0,1], [2,3] [4,5] .. .'? – NathanOliver

cevap

7

Bu çalışmalı, bir std::unordered_sets:

Bu temelde tamsayılar aşağıdakilerden yineleyici eşdeğerdir
auto set_end = s.end(); 
for (auto ai = s.begin(); ai != set_end; ++ai) { 
    for (auto bi = std::next(ai); bi != set_end; ++bi) { 
     // *ai, *bi 
    } 
} 

:

for (int i = 0; i < n; ++i) { 
    for (int j = i + 1; j < n; ++j) { 
     // i, j 
    } 
} 
+0

Eski moda bir 'for' döngüsü üzerinde std :: for_each'i öneririm. – caps

+2

@caps 'std :: for_each' yineleyici vermez ve iç döngü dış döngünün yineleyicisine bağlıdır. – orlp

+0

Sadece bir merak konusu olarak, döngülerdeki s.end() 'yerine 'set_end' kullanmanın bir nedeni var mı? – erip

1

Burada yarı jenerik formda orlp en çözümdür.

template<typename ForwardIterator, typename DestItr> 
auto cartesian_product(ForwardIterator b, ForwardIterator e, DestItr d) -> DestItr { 
    using std::next; 
    using std::for_each; 
    for (; b != e; ++b) { 
     for_each(next(b), e, [&](auto right){ 
      *d++ = std::make_tuple(*b, right); 
     }); 
    } 
    return d; 
} 

template<typename ForwardRange, typename DestItr> 
auto cartesian_product(ForwardRange r, DestItr d) -> DestItr { 
    using std::begin; 
    using std::end; 
    return cartesian_product(begin(r), end(r), d); 
} 

Live on Coliru.

Elbette, özel fanktorlar yerine make_tuple ve atama operatörünün kullanmak için aşırı yükleri alarak daha genel yapabiliriz. Standart kütüphane algoritmaları bunu yapma eğilimindedir. Bunu bir kütüphane için yazmış mıydım?

+0

Bu 'cartesian_product' ismini vermeyin, çünkü bu kesinlikle kartezyen ürünü __not__. Bir kümenin kendisi ile 2 kombinasyonudur. – orlp

+0

Hmm. Bir şey ... "self_combination"? 'Self_permutations_combination'? – caps

İlgili konular