erase und remove aus der stl


  • Mod

    Ich hatte das so interpretiert, dass die Ausgabesequenz keine Duplikate enthalten darf (als Konsequenz des remove-Aufrufs).
    Fellhuhns korrigierte Variante funktioniert, hat aber quadratische Komplexität.
    Besser wäre

    struct is_candidate_for_collection : std::unary_function<int,bool>
    {
        bool operator(int v) const { return v == 9 || v == 4; }
    };
    
    ...
    // Kopiere alle Kandidaten nach collectPoints:
    remove_copy_if(allPoints.begin(),allPoints.end(),std::back_inserter(collectPoints),std::not1(is_candidate_for_collection()));
    // Lösche alle Vorkommen in allPoints
    allPoints.erase(remove_if(allPoints.begin(),allPoints.end(),is_candidate_for_collection()),allPoints.end());
    
    // oder wir schreiben uns einen eigenen single-pass Algorithmus
    template<class ForwardIterator, class OutputIterator, class Predicate>
    ForwardIterator split_copy_if(ForwardIterator first, ForwardIterator last,OutputIterator out, Predicate pred)
    {
        ForwardIterator i = std::find_if(first,last,pred);
        if ( i == last )
            return i;
        for ( *out = *i, ++out, first = i, ++first; first != last; ++first )
        {
            if ( pred( *first ) )
            {
                *out = *first;
                ++out;
            }
            else
            {
                *i = *first;
                ++i;
            }
        }
        return i;
    }
    // mithin
    allPoints.erase(split_copy_if(allPoints.begin(),allPoints.end(),std::back_inserter(collectPoints),is_candidate_for_collection()),allPoints.end());
    

Anmelden zum Antworten