2016-03-31 10 views
3

Ich bin neu in C++.Vergleichen Sie alle Elemente eines std :: Vektor mit jedem anderen Element in demselben Vektor effizient

Ich versuche zu finden, wie man durch einen Vektor iteriert, um jedes Element mit jedem anderen Element zu vergleichen, wobei die Vergleichsreihenfolge irrelevant ist;

(a 'im Vergleich zu' b) = (b 'im Vergleich zu' a)

So Überprüfung eines bedeutet, dass Sie nicht jeden Wert zu jedem anderen Wert vergleichen müssen, nur die restlichen Einsen.

Ich habe etwas, das wie dieser TOY Algorithmus ist;

#include <vector> 

typedef std::vector<double> vector_t; 

int countTheFoo(const vector_t &v) 
{ 
    int fooFound {0}; 
    for (auto it1 = v.begin(); (it1 != v.end()); it1++) 
    { 
    for (auto it2 = it1.next(); (it2 != v.end()); it2++) 
    { 
     if testForFoo(*it1, *it2) 
     { 
     // Woot! Found some... 
     fooFound++; 
     } 
    } 
    } 
    return fooFound; 
} 

vector_t foo { 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 }; 

int numFoo {countTheFoo(foo)}; 

bin vergleiche ich tatsächlich Linien diejenigen zu finden, die nicht einfach verdoppelt schneidet aber die Technik wäre das gleiche.

Es ist das;

for (auto it2 = it1.next(); (it2 != v.end()); it2++) 

Teil, dass ich denke, könnte effizienter mit Lambdas getan werden.

Dieser Ansatz funktioniert, aber;

  • Ist es die effizienteste Art, diese Art von Iteration durchzuführen?

  • Kann es als Lambda mit std :: for_all() getan werden?

Vielen Dank.

+2

Ist eine größere als/kleiner als Beziehung definiert? Wenn ja, können Sie die Listen sortieren, und es wird möglich sein, alles zu vergleichen. –

+0

Weiß nicht, ob das funktionieren würde ... Ich vergleiche LINKS, die nicht einfache Zahlen INTERSECT, also suchte ich nach einer verallgemeinerten Form für die Lösung NICHT einfach verdoppelt. –

+0

Sie erhalten eine falsche cont, wenn der Vektor drei (oder mehr) gleiche Elemente enthält –

Antwort

1

Nein, Sie brauchen nicht (it1 != it2) weil durch die Definition Ihrer Schleife zu testen, auf it2, it2 wird immer größer ist als it1. Die Effizienz wird erhöht, wenn Sie diesen Ausdruck aus Ihrem Code löschen.

Sie wahrscheinlich könnte std::for_all verwenden, aber es ist nicht klar, dass das die Effizienz des Codes erhöhen würde.

+0

Natürlich. Realisierte das nach dem Posten. –

+0

Realisiert, dass nach der Buchung. Wird bearbeiten. –

0

Verwenden Sie eine std::set und eine einzelne Schleife, um zu überprüfen, ob der Wert im Vektor bereits in der Menge vorhanden ist; und wenn nicht, füge es ein.

Das ist wirklich was std::set ist für. Es wird schwierig sein, eine Lookup-Implementierung zu entwickeln, die std::set übertrifft.

+0

'std :: sort' kann" std :: set "leicht übertreffen – Slava

+1

std :: lower_bound und std :: binary_search auf sortierten Vektor sind beide binäre Suchvorgänge mit logarithmischer Kompexität. Nachteil ist, dass Sie entweder den Vektor sortieren oder Elemente in sortierter Weise einfügen müssen (wiederum mit z. B. lower_bound), was * Neuzuweisungen und Kopien auslösen kann. Bei relativ kleinen Datensammlungen ist sogar die lineare Suche (find_if) schneller als die Suche nach dem Satz aufgrund des Prozessor-Caching. –

+0

Das ergibt keinen Sinn. Wenn das Prädikat eine Äquivalenzrelation wäre und das OP Zugang zu einer kompatiblen schwachen Ordnung hätte, würde er viel besser tun, indem es einfach die Daten sortiert und benachbarte Elemente vergleicht (auch keine binäre Suche). – filipos

Verwandte Themen