Ich benötige einen binären Suchalgorithmus, der mit den C ++ STL-Containern kompatibel ist, ähnlich wie std::binary_search
im <algorithm>
Header der Standardbibliothek , aber ich brauche ihn, um den Iterator zurückzugeben, der auf das Ergebnis zeigt, und keinen einfachen Booleschen Wert, der mir sagt, ob das Element vorhanden ist.
(Nebenbei bemerkt, was zum Teufel hat das Standardkomitee gedacht, als es die API für binary_search definiert hat?!)
Mein Hauptanliegen hierbei ist, dass ich die Geschwindigkeit einer binären Suche benötige. Obwohl ich die Daten mit anderen Algorithmen finden kann, wie unten erwähnt, möchte ich die Tatsache nutzen, dass meine Daten sortiert sind, um die Vorteile einer binären Suche zu nutzen Suche, keine lineare Suche.
bisher lower_bound
und upper_bound
scheitern, wenn das Datum fehlt:
//lousy pseudo code
vector(1,2,3,4,6,7,8,9,0) //notice no 5
iter = lower_bound_or_upper_bound(start,end,5)
iter != 5 && iter !=end //not returning end as usual, instead it'll return 4 or 6
Hinweis: Ich kann auch einen Algorithmus verwenden, der nicht zum Standard-Namespace gehört, solange er mit Containern kompatibel ist. Wie zum Beispiel boost::binary_search
.
quelle
Antworten:
Es gibt keine solche Funktionen, aber Sie können eine einfache Verwendung schreiben
std::lower_bound
,std::upper_bound
oderstd::equal_range
.Eine einfache Implementierung könnte sein
Eine andere Lösung wäre die Verwendung von a
std::set
, die die Reihenfolge der Elemente garantiert und eine Methode bereitstelltiterator find(T key)
, die einen Iterator für das angegebene Element zurückgibt. Ihre Anforderungen sind jedoch möglicherweise nicht mit der Verwendung eines Satzes kompatibel (z. B. wenn Sie dasselbe Element mehrmals speichern müssen).quelle
*i == val
! Eher benutzen!(val < *i)
. Der Grund dafür ist , dass dielower_bound
Anwendungen<
nicht==
(dhT
nicht einmal erforderlich Gleichheit vergleichbar sein). (Siehe Scott Meyers ' Effective STL für eine Erklärung des Unterschieds zwischen Gleichheit und Äquivalenz .)end
. Bereiche in der C ++ - Standardbibliothek werden mit halboffenen Intervallen dargestellt: Der Enditerator "zeigt" nach dem letzten Element. Als solches kann es von Algorithmen zurückgegeben werden, um anzuzeigen, dass kein Wert gefunden wurde.Sie sollten einen Blick darauf werfen
std::equal_range
. Es werden zwei Iteratoren in den Bereich aller Ergebnisse zurückgesetzt.quelle
Es gibt eine Reihe von ihnen:
http://www.sgi.com/tech/stl/table_of_contents.html
Suchen nach:
Auf einem separaten Hinweis:
Sie dachten wahrscheinlich, dass die Suche nach Containern mehr als ein Ergebnis ergeben könnte. Aber gelegentlich, wenn Sie nur auf Existenz testen müssen, wäre auch eine optimierte Version schön.
quelle
Wenn std :: lower_bound für Ihren Geschmack zu niedrig ist, sollten Sie boost :: container :: flat_multiset überprüfen . Es ist ein Drop-In-Ersatz für std :: multiset, das mithilfe der binären Suche als sortierter Vektor implementiert wird.
quelle
Die kürzeste Implementierung, die sich fragt, warum sie nicht in der Standardbibliothek enthalten ist:
Von https://en.cppreference.com/w/cpp/algorithm/lower_bound
quelle
Überprüfen Sie diese Funktion, qBinaryFind :
Die Funktion ist im
<QtAlgorithms>
Header enthalten, der Teil der Qt- Bibliothek ist.quelle
std :: lower_bound () :)
quelle
Beispiel: Betrachten Sie ein Array, A = [1,2,3,4,5,6,7,8,9] Angenommen, Sie möchten den Index 3 durchsuchen. Beginnen Sie zunächst mit 0 = 0 und beenden Sie jetzt mit 9-1 = 8 , da start <= end; Mitte = 4; (Array [Mitte], das 5 ist)! = 3 Nun liegt 3 links von Mitte, da es kleiner als 5 ist. Daher suchen wir nur den linken Teil des Arrays. Daher ist jetzt Start = 0 und Ende = 3; mid = 2.Since array [mid] == 3, daher haben wir die Nummer erhalten, nach der wir gesucht haben. Daher geben wir seinen Index zurück, der gleich mid ist.
quelle
Eine Lösung, die die Position innerhalb des Bereichs zurückgibt, könnte wie folgt aussehen und nur Operationen für Iteratoren verwenden (dies sollte auch dann funktionieren, wenn der Iterator nicht rechnet):
quelle