2013-04-24 12 views
5

Ich bin auf der Suche nach einer Möglichkeit, Duplikate aus einem Vektor zu entfernen (nennen wir ihn den GroßenVektor: D). Ich kann nicht std :: sort gefolgt von std :: unique verwenden, da es keine Möglichkeit gibt, meine Objekte zu sortieren.Entfernen von Duplikaten aus einem nicht sortierbaren Vektor

theGreatVector enthält einige vector<Item*> (smallVectors)

ich eine Überlastung von == bekam für vector<Item*>, so kann ich es verwenden

Ich bin in der Lage de etwas in O (n²) erstellen, aber ich brauche Zeiteffizienz (theGreatVector.size() könnte 10⁵ oder 10⁶)

Gerade jetzt, was ich habe ist etwas wie das (i füllen mein Vektor nur, wenn smallOne ist nicht drin):

for(i=0;i<size;i++) 
{ 
    vector<Item*>smallOne = FindFacets(i) 
    if(smallOne doesnt belong to GreatOne) // this line already in O(n) :/ 
    { 
    theGreatOne.push_back(smallOne); 
    } 
} 

Wenn es eine Möglichkeit gibt, das auch in nlog (n) + n oder etwas niedriger als n² zu tun, wäre das großartig!

Vielen Dank

Azh

+0

Wenn Sie Wertegleichheit haben, ist es wahrscheinlich, dass Sie auch eine Reihenfolge definieren und eine Sortierung durchführen können. – juanchopanza

+0

was meinst du, du kannst deine objekte nicht sortieren? Sie können jedes Datenelement immer in ein 'std :: tuple' 'std :: binden und die lexikographische Anordnung dafür verwenden. – TemplateRex

+0

Was macht Ihr' == 'on' vector '? Vergleicht es "Größe" und Zeigerwerte, oder dereferenziert die Zeiger und vergleicht zugrunde liegenden Wert? Warum denkst du, dass '<' nicht ähnlich funktionieren kann, ist 'Item' irgendwie seltsam? Mit "Duplikaten" meinst du duplicate 'vector ', oder dupliziere 'Item *' in einem der 'vector ', oder dupliziere 'Item' in einem' Item * 'in einem der' vector '(ich nehme an Der Erste)? Ist die Reihenfolge von 'GreatOne' wichtig? Wie oft fügst du dazu noch hinzu? Lesen? Ändern? In welchem ​​Muster (viele Ergänzungen, dann nichts als viele Lektüren?) – Yakk

Antwort

0

Sie können immer std::tie jedes Datenelement in eine std::tuple und lexikographische Ordnung auf, dass verwenden, um einen Vektor von Zeigern auf Ihre große Datenstruktur zu sortieren. Sie können dann std::unique auf dieser Datenstruktur vor dem Kopieren der Ausgabe tun. Mit einer kleinen Modifikation können Sie die Duplikate auch entfernen, indem Sie den großen Item Vektor direkt sortieren.

#include <tuple> 
#include <memory> 
#include <vector> 

// tuples have builtin lexicographic ordering, 
// I'm assuming all your Item's data members also have operator< 
bool operator<(Item const& lhs, Item const& rhs) 
{ 
    return std::tie(lhs.first_data, /*...*/ lhs.last_data) < std::tie(rhs.first_data, /*...*/ rhs.last_Data); 
} 

int main() 
{ 
    // In the Beginning, there was some data 
    std::vector<Item> vec; 
    // fill it 

    // init helper vector with addresses of vec, complexity O(N) 
    std::vector<Item*> pvec; 
    pvec.reserve(vec.size()); 
    std::transform(std::begin(vec), std::end(vec), std::back_inserter(pvec), std::addressof<Item>); 

    // sort to put duplicates in adjecent positions, complexity O(N log N) 
    std::sort(std::begin(pvec), std::end(pvec), [](Item const* lhs, Item const* rhs){ 
     return *lhs < *rhs; // delegates to operator< for Item 
    });  

    // remove duplicates, complexity O(N) 
    auto it = std::unique(std::begin(pvec), std::end(pvec), [](Item const* lhs, Item const* rhs){ 
     return *lhs == *rhs; // assumes Item has operator==, if not use std::tuple::operator== 
    }); 
    pvec.erase(it, std::end(pvec)); 

    // copy result, complexity O(N) 
    std::vector<Item> result; 
    result.reserve(pvec.size()); 
    std::transform(std::begin(pvec), std::end(pvec), std::back_inserter(result), [](Item const* pelem){ 
     return *pelem; 
    }); 

    // And it was good, and done in O(N log N) complexity 
} 
+0

Sie müssen 'Item *', nicht 'Item' vergleichen. – juanchopanza

+0

@juanchopanza tnx, reparierte es. – TemplateRex

+0

Vielen Dank für diese Antwort, aber es ist ziemlich schwer für mich zu verstehen ^^ U schlagen vor, den Smallvector & Tuple stattdessen zu entfernen, richtig? – Azhrilla

Verwandte Themen