Am 29.07.2017 um 09:15 schrieb tomas@tuxteam.de:
On Sat, Jul 29, 2017 at 12:28:26AM +0200,
Urs Liska wrote:
> Am 28.07.2017 um 23:31 schrieb tomas@tuxteam.de:
[...]
>> Ich habe mir die mal angeschaut. Ich nehme mal an, die
ist:
>>
>>
02-data-structures/06-binary-search-trees/is_bst/is_bst.py
> Ja.
> Allerdings ist die bereits im master-Branch, was bedeutet,
dass die
> Aufgabe schon erfolgreich absolviert wurde (inzwischen, d.h.
seit meinem
> ersten Post).
Congrats :)
>> Bei der Methode is_bst(self, indeex=0) stehe ich noch auf
der
>> Leitung: was soll die Methode als Rückgabewert liefern?
>> Ich meine: was für eine Art Objekt?
>>
>> Wenn ich nicht ganz auf der Leitung stehe, dann vermute
ich
>> hier den Knoten :-)
> Das ist in der Tat recht kryptisch und hätte wohl eine
bessere
> Kommentierung verdient. Dann hätte ich auch den (allerdings
> konsequenzlosen) Fehler bemerkt ...
+1
> Der Rückgabewert der rekursiven Funktion ist eine Liste mit
den
> Randwerten der linken und rechten Kinder und dem aktuellen
Knoten in der
> Mitte. "Natürlicher" wäre die Rückgabe von "left + [index] +
right",
OK. Darauf wäre ich allerdings nicht gekommen, zumal is_bst einem
das
Hirn schon auf ein boolean "polt" (is this thing a binary search
tree?).
Grrr, das muss ich zugeben. Die Funktion sollte anders heißen.
Im Wesentlichen ist es so, dass der Baum in seiner natürlichen
Ordnung durchlaufen wird. Sofern eine Fehlerbedingung festgestellt
wird, bricht sie ab, andernfalls läuft sie durch und gibt
"irgendwas" zurück - dann ist der Baum korrekt.
Semantisch richtig wäre wohl
def main():
tree = TreeOrders()
if len(tree.nodes)
== 0:
print("CORRECT")
tree.traverse()
print("CORRECT")
Das verführt einem dazu, sich diese "Frage"
rekursiv vorzustellen
is_bst(tree):
return tree.left.val < tree.val \
and tree.val < tree.right.var \
and is_bst(tree.left) \
and is_bst(tree.right)
(das ist natürlich salopp formuliert, bei Deiner Darstellung des
Baums
müssen eher solche Dinge stehen wie
self.value(self.left(index)) < self.value(index) ...
bzw.
is_bst(self.left(index))...
... you get the idea. Man muss natürlich damit klarkommen, dass
diese
Methoden manchmal None liefern, was den Ausdruck etwas
unübersichtlich
macht (bei den Vergleichen).
Ich glaube nicht, dass das funktionierten würde. Wenn ich an einem
gegebenen Knoten für links und rechts nur einen Boolean-Wert
zurückbekomme, kann ich nicht mit dem aktuellen Knoten vergleichen
(wie du unten auch schreibst). Daher muss die rekursive Funktion
schon die Knoten-Werte des Subtrees zurückgeben.
Anders als bei Deinem Ansatz muss man also nicht "mittendrin"
herausspringen (d.h. fail()), sondern das Ergebnis entsteht
rekursiv. Im
Fehlerfall ist das "Herausspringen" schneller, natürlich.
> wodurch rekursiv eine Liste mit dem gesamten Inhalt des Baums
in
> natürlicher Ordnung entsteht. Diese Liste kann allerdings
recht lang
> werden und kostet offensichtlich zu viel Rechenzeit.
> Falsch ist, dass das mittlere Element nicht "[index]" sein
dürfte,
> sondern der tatsächliche Schlüsselwert, nämlich
"[self.value(index)]".
> Da dieser mittlere Wert aber überhaupt nicht gebraucht wird,
ist der
Das verstehe ich nicht: der mittlere Wert muss doch zwischen den
linken
und den rechten liegen, damit der Baum sortiert ist? Muss man das
nicht
auch prüfen?
Ja, natürlich. Am gegebenen Knoten muss ich prüfen, ob der höchste
Wert des linken Teilbaums kleiner als und der niedrigste Wert des
rechten Teilbaums größer als der aktuelle Wert ist. Nach oben
weitergeben muss ich aber nur den niedrigsten und größten Wert des
sich ergebenden Teilbaums, damit der nächsthöhere Knoten ebendiesen
Vergleich anstellen kann. Der Wert des aktuellen Knotens wird
überhaupt nicht weiter verwendet, und deswegen ist es auch nicht
aufgefallen, dass ich hier den Index statt des Werts weitergegeben
habe.
Ich glaube, ich probiere das nochmal zu korrigieren (auch wenn die
Aufgabe ja schon offiziell akzeptiert wurde.
> Fehler nicht aufgefallen. DIESE Aufgabe ist also inzwischen
erfolgreich
> gelöst.
Bestens. Hängst Du noch irgendwo?
Ja, wie gesagt habe ich offene Fragen auf dem Issue-Tracker abgelegt
(ich habe das Repository jetzt doch auch öffentlich sichtbar
gemacht):
https://git.openlilylib.org/uliska/algorithms-and-datastructures/issues
Im Moment sind es zwei unterschiedlich geartete Fragen:
1)
Bei der Aufgabe, Substrings zu hashen, komme ich einfach nicht über
einen Testfall hinweg, bei dem der Algorithmus zu lange braucht.
Hier muss es entweder eine Optimierung geben, die ich nicht gefunden
habe (z.B. dass unnötig String-Kopien erzeugt werden oder es eine
unnötige Schleife gibt) oder einen Sonderfall, der meinen
Algorithmus in die Ecke (bzw. in einen Kreis) treibt):
https://git.openlilylib.org/uliska/algorithms-and-datastructures/issues/3
2)
Bei der Frage, ob ein Graph bipartit ist, scheitere ich an einer
"falschen Antwort". Hier muss ich sagen, dass mir die Implikationen
der Aufgabe noch etwas schwammit sind und mein Ansatz daher
vielleicht zu naiv ist. Ich suche per Breitensuche nach erreichbaren
Knoten und färbe alle Nachbarn eines Knotens mit der "anderen" Farbe
ein. Wenn ich auf einen Knoten stoße, der bereits entdeckt wurde,
aber dieselbe Farbe wie ein aktueller Knoten hat, erkenne ich den
Graphen als nicht bipartit.
Bei allen angegebenen Beispiel-Eingaben funktioniert das auch, aber
der Grader weist einen (mir unbekannten) Test-Fall ab.
Es gibt noch ein paar weitere Aufgaben, die ich noch nicht gelöst
habe, aber die sind noch in dem Stadium, in dem ich versuche,
alleine klarzukommen (wie schon gesagt: Es geht mir ja nicht darum,
die Aufgaben zu bestehen und das Zertifikat zu bekommen, sondern
darum, die Sachen zu verstehen).
HG
Urs
lg
-- t
> _______________________________________________
> Freiburger Linux User Group
> Mail an die Liste: flug@lug-freiburg.de
> Mailingliste verwalten (u.a. abbestellen): https://lug-freiburg.de/mailman/listinfo/flug
--
ul@openlilylib.org
https://openlilylib.org
http://lilypondblog.org