Der Unterschied zwischen basic binären Suche für die Obere Grenze und untere Grenze?
In dem Artikel http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binarysearch-Methode, bespricht die Autorin die binäre Suche. Er macht einen Unterschied zwischen der Suche nach dem niedrigsten Wert, wo etwas wahr ist, und der höchste Wert, wo etwas falsch ist.
Das array durchsucht werden, sieht etwas aus wie:
false false false true true
Ich bin neugierig, warum diese beiden Fälle sind unterschiedlich. Warum können Sie nicht einfach finden, die niedrigsten Wert, welcher true ist, dann subtrahieren eines zu finden, der höchste Wert, der falsch ist?
Edit2: Ok, also verstehe ich das untere vs. Obere Schranke. Nun, ich habe Schwierigkeiten zu verstehen, bei der Suche für die kleinste Ganzzahl, die größer oder gleich der Abfrage, warum können wir nicht einfach ändern if(mid>query)
zu if(mid>=query)
haben und es tun untere statt Obere Schranke.
Edit: Hier ist was in dem Artikel hieß es:
"Jetzt bekommen wir endlich den code implementiert die binäre Suche wie beschrieben in diesem und dem vorherigen Abschnitt:
binary_search(lo, hi, p):
while lo < hi:
mid = lo + (hi-lo)/2
if p(mid) == true:
hi = mid
else:
lo = mid+1
if p(lo) == false:
complain //p(x) is false for all x in S!
return lo //lo is the least x for which p(x) is true
...
Wenn wir wollten, um die letzten x, für die p(x) ist falsch, wir würden ausdenken (mit einer ähnlichen Begründung wie oben), so etwas wie:
binary_search(lo, hi, p):
while lo < hi:
mid = lo + (hi-lo+1)/2 //note: division truncates
if p(mid) == true:
hi = mid-1
else:
lo = mid
if p(lo) == true:
complain //p(x) is true for all x in S!
return lo //lo is the greatest x for which p(x) is false
."
Der Artikel im bezieht, impliziert, dass dies der Fall ist, wenn wir uns binäre Suche; ich glaube, das ist auch eine Notwendigkeit für die binäre Suche, um auch auf die situation.
sicher, aber konnte Sie leicht überprüfen, mit wie
if(lo==0&&works(lo)==true)return false
?InformationsquelleAutor John Targaryen | 2015-02-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den unteren und oberen Grenze einer binären Suche werden die höchste und die niedrigste position, wo der Wert eingefügt werden könnte, ohne die Bestellung. (In der C++ - standard-Bibliothek, diese Schranken werden vertreten durch Iteratoren verweisen auf das element, bevor der Wert eingefügt werden könnte, aber das Konzept ist nicht wesentlich verändert.)
Nehmen, zum Beispiel, eine sortierte Auswahl
In eine binäre Suche für
3
wir habenUnd in eine binäre Suche für
5
:Die untere und Obere Schranke gleich sind, wenn das element nicht vorhanden in der Auswahl. In eine binäre Suche für
8
:Den Autor des Artikels, auf den Sie sich beziehen-Sätze ist in die äquivalenten Begriffe "kleiner als" und "größer als", so dass bei einer Suche von 5,
Den C++ - Iteratoren wird, in all diesen Fällen beziehen sich auf das element direkt hinter der Schranke. Das heißt:
3
, der iterator zurückgegebenstd::lower_bound
finden würde, um3
und der vonstd::upper_bound
finden würde, um4
5
, der iterator zurückgegebenstd::lower_bound
würde sich auf den ersten5
und der vonstd::upper_bound
finden würde, um6
8
, würden beide beziehen sich auf9
Dies ist, weil die Konvention in den C++ - standard-Bibliothek für Insertionen ist die übergabe eines iterator bezogen auf das element, vor dem das neue element eingefügt werden soll. Zum Beispiel, nach
vec
enthalten würde1, 2, 3, 4, 5, 5, 5, 6, 7, 9
.std::lower_bound
undstd::upper_bound
Folgen dieser Konvention, so dassArbeit wie gewünscht und lassen
vec
sortiert.Mehr im Allgemeinen, dies ist ein Ausdruck der Art und Weise Bereiche angegeben werden, die im C++ standard-Bibliothek. Der Anfang iterator für einen Bereich bezieht sich auf das erste element des Bereichs (wenn überhaupt), während der Ende-iterator bezieht sich auf das element (falls vorhanden) direkt hinter das Ende der Reihe. Ein weiterer Weg, um es zu betrachten ist, dass die Iteratoren zurückgegeben
std::lower_bound
undstd::upper_bound
span die Anzahl der Elemente im gesuchten Bereich, sind äquivalent zu den gesuchten element.Dieser Bereich ist leer, wenn das element nicht in der Auswahl, so dass
lower_bound
undupper_bound
wieder den gleichen iterator und sonstlower_bound
gibt einen iterator bezogen auf das erste element der gesuchte Bereich entspricht das der Suche nach Wert, währendupper_bound
gibt einen iterator bezogen auf das element (falls vorhanden), die direkt hinter der letzten ein solches element.Im C++ - standard-Bibliothek Begriffe, die Iteratoren erhalten Sie von
lower_bound
undupper_bound
würde sowohl in Referenz 9 denn bevor dieses element ist sowohl die höchste und die niedrigste Stelle, wo eine 8 eingefügt werden könnte. Der Ort, wo das element wirklich konnte nicht eingefügt werden, wird immer einer der Lücken oder enden, aber.lower_bound
undupper_bound
handeln in übereinstimmung mit der Allgemeinen iterator-Konventionen in der stdlib es -- es ist das gleiche fürvector::insert
, wo die Weitergabevec.begin() + 1
wird es fügen Sie das neue element vor dem aktuellen zweiten element, und in anderen, ähnlichen zusammenhängen. Dies ist, so dass Sie weitergeben können, das Ergebnislower_bound
undupper_bound
direkt auf diese Funktionen und haben Sie das richtige tun.ist das erste element, das
upper_bound
ist das erste element, das mehr als 8. In beiden Fällen, das ist die 9.InformationsquelleAutor Wintermute
Wenn das array wird immer
Dann den index, bevor die, die Sie finden, wird immer falsch sein, es sei denn, Sie finden true
index 0
. Eine weitere Grenze Falle, wie bereits in meinem Kommentar oben, ist, wenn Sie nicht findentrue
. Dann, die höchsten false wird der Letzte Teil der Reihe.if(array[0]==true||array[array.size]==false)return false
? Auch, wie würde die änderung im code, der dieses problem beheben?Das ist sozusagen der Punkt. Wenn
x
ist der index fürtrue
,x-1
ist nicht zwingend die Grenze für diefalse
. Sie müssen sagenif x > 0 && !array[x-1]
(zweiter Teil optional).InformationsquelleAutor royhowie
Werden die beiden algorithmen offensichtlich unterscheiden sich in der Bedingung von dem, was geschehen sollte, wenn gibt es keine
true
oder keinefalse
Wert so wie er ist eigentlich ziemlich offensichtlich aus dem code-snippet: wenn Sie den niedrigsten Wert, wobei der Werttrue
und subtrahieren Sie 1 von dieser position aus zu finden, der höchste Wert nachgebenfalse
ein Falsches Ergebnis produziert wird, als dort ist kein solches Objekt. Da die algorithmen einfach auf verschiedene Elemente, die den Umgang mit dem Auffinden der entsprechenden Elemente direkt anstatt mit einem speziellen Fall auch vermieden, dass der Umgang mit einem speziellen Fall, die Verringerung der Menge an code. Seit Sonderfall-code neigt dazu, nur einmal ausgeführt werden für jeden Algorithmus-Aufruf es ist voraussichtlich leicht schlechter als die Vermeidung der Besondere Fall. Das ist etwas, was Wert sein kann, Messen.Beachten Sie, dass das code-Beispiel ist nicht C++ - trotz der Frage, die tagged-C++. Als ein Ergebnis ist es nicht idiomatischen C++. Der typische Ansatz in C++ zu implementieren, die so etwas wie
lower_bound()
oderupper_bound()
ist, geeignete Iteratoren. Diese algorithmen nicht "beschweren", wenn es kein entsprechendes element als würden Sie produzieren nur einen iterator, der entsprechenden position, d.h., ein iterator auf den Anfang fürstd::lower_bound()
und ein past-the-end-iterator fürstd::upper_bound()
.InformationsquelleAutor Dietmar Kühl