2014-09-22 12 views
6

Czy C++ ma odpowiednik pytfona set.pop()? Przeglądałem dokumentację dla unordered_set s here, ale nie wydaje się, że istnieje sposób na 1. Dostęp do dowolnego elementu i/lub 2. Dostęp + usunięcie dowolnego elementu (popping).Równoważna z pythoniem set.pop() dla nieuporządkowanych zbiorów języka C++

+0

Ponieważ jest to * nieuporządkowany *, czy nie jest początkiem() i końcem() "arbitralny" z definicji? Python prawdopodobnie robi coś podobnego pod kołdrą. – swstephe

+0

Prawda ... Mogę po prostu trzymać się tej implementacji mojego programu. – hlin117

Odpowiedz

2

Zauważmy, że C++ Standardowa biblioteka jest celowo zaprojektowany tak, że różne specyfikacje kontenerów nie zawierają „GET i usuwania” funkcję: na przykład dla vector, masz back(), który zwraca wartość na końcu, i masz pop_back(), który usuwa wartość na końcu, ale nie zwraca go.

Przyczyną tego może być treść osobnego pytania.

Tak więc, czego faktycznie potrzebujesz, to metoda uzyskania elementu (np. begin() zgodnie z sugestiami w komentarzach), a następnie usunięcie go po uzyskaniu go (np. erase(iterator), jak wspomniano w drugiej odpowiedzi).

+0

wszelkie odniesienia do przyczyn tego zamiaru według normy? –

7

Można albo pop pierwszy element

auto i = *set.begin(); 
set.erase(set.begin()); 

lub jeśli jesteś zbyt zaniepokojeni wewnętrznego uporządkowania realizacji zdefiniowanej z wiader (podpowiedź: prawdopodobnie nie powinno być), można usunąć element losowy z czymś

#include <unordered_set> 
#include <iostream> 
#include <random> 

int main() 
{ 
    std::unordered_set<int> set{0, 1, 2, 3, 4, 5}; 
    std::default_random_engine ran{std::random_device{}()}; 

    auto it = set.begin(); 
    std::advance(it, std::uniform_int_distribution<>{0, set.size() - 1}(ran)); 

    std::cout << *it << '\n'; 
    set.erase(it); 
} 

Powyższe nie jest jednak szczególnie efektywny i może być lepiej przez wypełnienie std::vector, usuwanie duplikatów, losowanie kolejności, a potem po prostu pop_back ing z elemen ts.

#include <algorithm> 
#include <vector> 
#include <iostream> 
#include <random> 

int main() 
{ 
    std::vector<int> vec{0, 1, 2, 3, 3, 4, 5, 5}; 
    std::sort(vec.begin(), vec.end()); 
    vec.erase(std::unique(vec.begin(), vec.end()), vec.end()); 

    std::shuffle(
    vec.begin(), 
    vec.end(), 
    std::default_random_engine{std::random_device{}()} 
); 

    while (!vec.empty()) { 
    std::cout << vec.back() << '\n'; 
    vec.pop_back(); 
    } 
} 

(nb zależności od używanej platformy random_device nie może być bardzo dobre nasienie).