Pytanie std :: usuwanie elementów wektorowych spełniających pewne warunki


Jak mówi tytuł, chcę usunąć / scalić obiekty w wektorze, które spełniają określone warunki. To znaczy, wiem, jak usunąć liczby całkowite z wektora, który ma na przykład wartość 99.

Usunięcie idiomu Scotta Meyersa:

vector<int> v;
v.erase(remove(v.begin(), v.end(), 99), v.end());

Załóżmy jednak, że jeśli masz wektor obiektów, który zawiera zmienną składową opóźnienia. A teraz chcę wyeliminować wszystkie obiekty, których opóźnienia różnią się tylko o mniej niż określony próg i chcą połączyć / scalić je z jednym obiektem.

Wynik procesu powinien być wektorem obiektów, w którym różnica wszystkich opóźnień powinna wynosić co najmniej określoną wartość progową.


14
2018-06-24 08:16


pochodzenie


Posługiwać się remove_if. - ForEveR
remove_if - BoBTFish
"Chcę wyeliminować wszystkie obiekty, których opóźnienia różnią się tylko o mniej niż określony próg" - Czy mógłbyś to rozwinąć? Różni się od czego? Inne elementy w kontenerze? Pobliskie elementy? Pewna konkretna wartość? - Benjamin Lindley
możliwy duplikat Usuwanie elementów z C ++ std :: vector - stijn
Załóżmy, że wektor zawiera pewne obiekty, obiekt o1 i obiekt o2 z opóźnieniem o1.delay=10 i o2.delay=50, więc mają względne opóźnienie 40. Ta różnica opóźnienia jest zbyt mała, aby była brana pod uwagę, dlatego chcę się zastanowić o1 i o2 jako jeden obiekt zamiast dwóch oddzielnych obiektów. - antibus


Odpowiedzi:


std::remove_if przychodzi na ratunek!

99 zostanie zastąpione przez UnaryPredicate to filtrowałoby twoje opóźnienia, do których zamierzam użyć funkcji lambda.

A oto przykład:

v.erase(std::remove_if(
    v.begin(), v.end(),
    [](const int& x) { 
        return x > 10; // put your condition here
    }), v.end());

23
2018-06-24 08:18



10 musi być zakodowanych! - user1436187
@ user1436187 co? - Bartek Banachewicz
Warunek nie może być zmienny. Na przykład wprowadzenie max zamiast 10. - user1436187
@ user1436187 uh, czemu nie? - Bartek Banachewicz
@ user1436187 musi pochodzić z zewnętrznego zakresu. Zdefiniuj przed v.erase() zadzwoń i przejdź do lambda w środku []. - Bartek Banachewicz


Używanie funkcji predykatu (idiomatyczny sposób w C ++ 11):

v.erase(remove_if(
            v.begin(), v.end(), bind(greater<int>(), _1, 99)),
        v.end());

0
2018-06-24 08:37



odjechany bind+1 za to samo. - Bartek Banachewicz
Osobiście uważam, że lambdas bind w większości przestarzałe. Są one o wiele bardziej użyteczne, a nawet w takich prostych przypadkach jak ten bind zadziała, lambda jest znacznie łatwiejsza do zrozumienia i zapamiętania składni. - Benjamin Lindley
@BenjaminLindley Zgoda. Z drugiej strony, jeśli nie masz C ++ 11, boost::bind jest nadal przydatny. - James Kanze