Die Kurzgeschichte
Ein berühmter Informatiker, Tarjan , schrieb vor Jahren ein Buch. Es enthält absolut bizarren Pseudocode. Würde es bitte jemand erklären?
Die lange Geschichte
Tarjan ist für viele Leistungen bekannt, einschließlich der Tatsache , dass er der Miterfinder der war spreizen Bäume . In den 1980er Jahren veröffentlichte er ein Buch mit dem Titel " Datenstrukturen und Netzwerkalgorithmen ".
Der gesamte Pseudocode in Tarjans Buch ist in einer eigenen Sprache verfasst. Die Pseudocode-Konventionen sind sehr reglementiert. Es ist fast eine wahre Sprache, und man könnte sich vorstellen, einen Compiler dafür zu schreiben. Tarjan schreibt, dass seine Sprache auf den folgenden drei basiert:
Ich hoffe, dass jemand, der mit einer oder zwei der oben genannten Sprachen oder dem Werk von Tarjan vertraut ist, meine Frage beantworten kann.
Ein Beispiel für eine in Tarjans Sprache geschriebene Funktion ist unten dargestellt:
heap function mesh (heap nodes h1, h2);
if key(h1) > key(h2) → h1 ⟷ h2 fi;
right (h1) := if right(h1) = null → h2
|right(h1) ≠ null → mesh (right(h1), h2) fi;
if rank (left (h1)) < rank (right (h1)) → left(h1) ⟷ right(h1) fi;
rank (h1) := rank(right(h1)) + 1;
return h1,
end mesh;
Ich habe viel Pseudo-Code gesehen, aber ich habe noch nie so etwas wie Tarjan gesehen. Wie funktioniert Tarjans Pseudocode? Wie können Beispiele für Tarjans Pseudocode so umgeschrieben werden, dass sie eher wie C oder Java aussehen? Es muss nicht einmal C oder Java sein. Das if-else-Konstrukt in Tarjans Sprache unterscheidet sich nicht nur von den Sprachen der C-Familie, sondern auch von Python, MATLAB und vielen anderen.
quelle
return
Aussage wirklich mit einem Komma?Antworten:
Inhaltsverzeichnis
Ich werde meine Erklärung von Tarjans Pseudocode in die folgenden Abschnitte unterteilen:
->
&|
Operatoren):=
und=
)else if
aber keinelse
Konstrukt:= if
Zusätzliche Beispiele für Tarjan
if
und:= if
5.5. Tarjan Arrays (oder Listen)
Zusammenfassung der Operatoren
⟷
)(1) Tarjans If-else-Blöcke
(die Betreiber
→
und|
)Das
if-else
Konstrukt ist vielleicht die grundlegendste Kontrollstruktur in Tarjans Sprache. Zusätzlich zu C-ähnlichen if-Blöcken ist das Verhalten von if-else in Tarjans Zuweisungen und Tarjans while-Schleifen nahezu integriert. Tarjans Pfeiloperator->
(oder →) ist ein Trennzeichen zwischen der Bedingung einer if-Anweisung und dem Ausführungsblock einer if-Anweisung.In Tarjans Sprache könnten wir zum Beispiel haben:
Wenn wir die obige Zeile des Tarjan-Codes teilweise in C oder Java übersetzen, erhalten wir Folgendes:
Anstelle einer geschweiften Klammer (wie in C und Java) beendet Tarjan einen
if
Block mit einer ALGOL-ähnlichen Rückwärtsschreibung des Schlüsselworts:fi
Wenn wir das obige Beispiel weiter übersetzen, erhalten wir:
(2) Zuordnungs- und Gleichheitsprüfungen (
:=
und=
)Tarjan übernimmt diese Operatoren von ALGOL (später auch in Pascal zu sehen).
Tarjan verwendet
=
für Gleichheitstests keine Zuweisungen (so funktioniert es wie Java==
).Für die Zuordnung verwendet Tarjan
:=
, was wie Java funktioniert=
.Wenn wir also unser Beispiel weiter übersetzen, haben wir:
Ein vertikaler Strich (oder "Pipe" oder
|
) in Tarjans Sprache entspricht demelse if
Schlüsselwort in C oder Java.In Tarjans Sprache könnten wir zum Beispiel haben:
Der obige Tarjan-Code übersetzt:
(3)
else if
nur und keinelse
KonstruktZuvor habe ich die Grundlagen von
if
-statements behandelt, ohne die Nuancen zu beschreiben. Wir werden jedoch nicht auf ein kleines Detail eingehen. Die letzte Klausel in einem Tarjan-ian-if-else
Block muss immer einen arrow (→
) -Operator enthalten. Als solches gibt es keine nurelse
in Tarjans Spracheelse if
. Das, waselse
in Tarjans Sprache einem Block am nächsten kommt, ist die Testbedingung ganz rechtstrue
.In C / Java hätten wir:
Beispiele sind leichter zu verstehen als allgemeine Beschreibungen. Nun, da wir einige Beispiele kennen, wissen wir, dass die allgemeine Form eines Tarjans if-else-Konstrukts wie folgt lautet:
Der Charakter
|
ist wieif else
Der Charakter
→
trennt die Testbedingung von der zu erledigenden Aufgabe.(4) Betreiber der bedingten Zuteilung von Tarjan
:= if
Tarjan
if
kann auf zwei verschiedene Arten verwendet werden. Bisher haben wir nur eine der Verwendungen des Tarjaner beschriebenif
. Etwas verwirrend ist, dass Tarjan immer noch die Notation / Syntaxif
für den zweiten Typ vonif
-construct verwendet. Wasif
verwendet wird, basiert auf dem Kontext. Das Analysieren des Kontexts ist eigentlich sehr einfach, da der zweite Tarjan-Typif
immer von einem Zuweisungsoperator voreingestellt wird.Zum Beispiel könnten wir den folgenden Tarjan-Code haben:
Beginnen Sie den Exkurs
Nachdem Sie eine Weile mit Tarjan-Code gearbeitet haben, gewöhnen Sie sich an die Reihenfolge der Operationen. Wenn wir die Testbedingung im obigen Beispiel in Klammern setzen, erhalten wir:
a = 4
ist keine Zuweisungsoperation.a = 4
ist wiea == 4
- es gibt wahr oder falsch zurück.Exkurs beenden
Es kann helfen , zu denken ,
:= if
wie Syntax für einen einzelnen Bediener, die sich von:=
undif
in der Tat werden wir zum beziehen:= if
Operator als „bedingte Zuweisung“ Operator.Denn
if
wir listen auf(condition → action)
. Für die:= if
Auflistung,(condition → value)
wovalue
sich der Wert auf der rechten Seite befindet, können wir ihn auf der linken Seite zuweisenlhs
in C oder Java könnte so aussehen:
Betrachten Sie das folgende Beispiel für "bedingte Zuweisung" im tarjanischen Code:
# Tarjan-Instanziierung von Beispiel 5 x: = a = 4 → 9 | a> 4 → 11 | wahr → 99 fi
In C / Java hätten wir:
(5) Zusammenfassung der Betreiber:
Bisher haben wir:
:=
...... Zuweisungsoperator (C / Java=
)=
...... Gleichheitstest (C / Java==
)→
...... Trennzeichen zwischen Testbedingung eines if-Blocks und dem Body eines if-Blocks|
..... C / Java sonst-wennif ... fi
..... wenn-sonst blockieren:= if... fi
..... Bedingte Zuweisung basierend auf einem if-else-Block(5.5) Tarjan Listen / Arrays:
Tarjans Sprache verfügt über eingebaute Array-ähnliche Container. Die Syntax für Tarjan-Arrays ist viel intuitiver als die Notation für Tarjan-
if else
Anweisungen.Auf Tarjan-Array-Elemente wird mit Klammern zugegriffen
()
, nicht mit eckigen Klammern[]
Die Indizierung beginnt um
1
. Somit,Unten sehen Sie, wie Sie ein neues Array mit dem 1. und 5. Element von erstellen
[1, 2, 3, 4, 5, 6, 7]
Der Gleichheitsoperator ist für Arrays definiert. Der folgende Code wird gedruckt
true
Tarjans Weg zu testen, ob ein Array leer ist, besteht darin, es mit einem leeren Array zu vergleichen
Sie können eine Ansicht (nicht eine Kopie) eines Unterarrays erstellen, indem Sie dem Operator in
()
Kombination mit mehrere Indizes bereitstellen..
(6) Zusätzliche Beispiele für Tarjan
if
und:= if
Das Folgende ist ein weiteres Beispiel für eine bedingte Tarjan-Zuweisung (
:= if
):(true --> b)
ist die am weitesten links stehende(cond --> action)
Klausel mit einer wahren Bedingung. Somit hat das ursprüngliche Zuweisungsbeispiel 6 das gleiche Zuweisungsverhalten wiea := b
Unten sehen Sie unser bisher kompliziertestes Beispiel für Tarjan-Code:
Das Folgende ist eine Übersetzung von Tarjans Code zum Zusammenführen zweier sortierter Listen. Das Folgende ist nicht genau C oder Java, aber es ist C / Java viel näher als die Tarjan-Version.
Unten ist noch ein Beispiel für Tarjan-Code und eine Übersetzung in etwas ähnlichem wie C oder Java:
Unten ist die C / Java-Übersetzung:
(7) Tarjans Doppelpfeil-Operator (
<-->
)Unten sehen Sie ein Beispiel für Tarjan-Code:
Was macht ein Doppelpfeil (
⟷
) in Tarjans Sprache?Nun, fast alle Variablen in Tarjans Sprache sind Zeiger.
<-->
ist ein Swap-Vorgang. Die folgenden Ausdrucketrue
Nach dem Durchführen
x <--> y
,x
zeigt auf das Objekt , dasy
zu und Punkt verwendet ,y
um die Objektpunkte , diex
bis zu Punkt verwendet.Nachfolgend finden Sie eine Tarjan-Anweisung mit dem
<-->
Operator:Unten ist eine Übersetzung vom obigen Tarjan-Code in einen alternativen Pseudocode:
Alternativ könnten wir haben:
Unten sehen Sie ein Beispiel für eine der Funktionen von Tarjan, die den
⟷
Operator verwenden:Unten ist eine Übersetzung von Tarjans
mesh
Funktion in Pseudocode, der nicht C ist, sondern eher wie C aussieht (relativ gesehen). Dies soll veranschaulichen, wie der Tarjan-⟷
Operator funktioniert.(8) Tarjans do-Schleifen sind wie C / Java-while-Schleifen
Tarjans Sprache
if
undfor
Konstrukte sind C / Java-Programmierern vertraut. Das Tarjan-Schlüsselwort für eine while-Schleife lautet jedochdo
. Alledo
-loops enden mit dem Schlüsselwortod
, bei dem es sich um die umgekehrte Schreibweise handeltdo
. Unten ist ein Beispiel:Im C-Pseudocode haben wir:
Das obige ist eigentlich nicht ganz richtig. Eine Tarjan-do-Schleife ist wirklich ein C / Java
while(true)
mit einem darin verschachtelten if-else-Block. Eine wörtlichere Übersetzung des Tarjan-Codes lautet wie folgt:Unten haben wir eine kompliziertere Tarjan-
do
Schleife:Der C / Java-Pseudocode für die komplizierte Tarjan-
do
Schleife lautet wie folgt:(9) Tarjans Bedingungszuweisungsoperator mit allen falschen Bedingungen
Obwohl die obige ausführliche Erklärung die meisten Dinge abdeckt, bleiben einige Fragen immer noch ungelöst. Ich hoffe, dass eines Tages jemand anderes eine neue, verbesserte Antwort auf der Grundlage meiner Antwort schreiben wird, die diese Probleme beantwortet.
Insbesondere wenn der Operator für bedingte Zuweisungen
:= if
verwendet wird und keine Bedingung zutrifft, ist mir nicht bekannt, welcher Wert der Variablen zugewiesen wird.Ich bin nicht sicher, aber es ist möglich, dass keine Zuordnung vorgenommen wird zu
x
:Möglicherweise müssen Sie die in einer
:= if
Anweisung angegebene linke Variable zuvor deklarieren. In diesem Fall hat die Variable auch dann noch einen Wert, wenn alle Bedingungen falsch sind.Alternativ stellen möglicherweise nur falsche Bedingungen einen Laufzeitfehler dar. Eine andere Alternative besteht darin, einen speziellen
null
Wert zurückzugeben undnull
im linken Argument der Zuweisung zu speichern .quelle
=
Vergleiche wie Zuweisungen gemeint sind (wenn ich jemals eine Sprache geschrieben habe, würde ich einen Syntaxfehler daraus machen und nur:=
und haben==
). Auf der anderen Seite ist der Swap-Operator die Art von Dingen, die nur in spezialisierten Sprachen vorkommen würden, in denen es sich um eine übliche Operation handelte. obwohl in anderen Sprachen, könnte man davon ausgehen , nur eine Bibliotheksfunktion aufgerufenswap
und ersetzth1 ⟷ h2
mit ,swap(h1, h2)
anstatt die Umsetzung jedes Mal auszuschreiben.[1, 2] = [1, 2, 3, 4, 5]
stimmt das?|
Bediener ist ein Wächter . Sie werden in Haskell (und ich glaube anderen funktionalen Sprachen) in Funktionsdefinitionen verwendet:f x | x == 0 = 1; x == 1 = 1; otherwise = f (x-1) + f(x-2)
Hierotherwise
ist ein Alias fürTrue
undf
definiert die Fibonacci-Zahlen.Nie zuvor gesehen, aber ich denke, ich kann aus dem Kontext ableiten, was gemeint ist. Vermutlich
⟷
muss es sich um eine Swap-Operation handeln. Esif G1 -> S1 | G2 - >S2 | ... fi
handelt sich um ein Konstrukt vom Typ if / then / else, das ebenfalls einen Wert zurückgibt, wie der ternäre?:
Operator in C und Java.Mit dieser Hand könnten wir die obige Funktion in einer Java-ähnlichen Sprache wie folgt schreiben:
quelle