Julia Language
während Loops
Suche…
Syntax
- während cond; Karosserie; Ende
- brechen
- fortsetzen
Bemerkungen
Die while
Schleife hat keinen Wert. Obwohl es in Ausdrucksposition verwendet werden kann, ist der Typ Void
und der erhaltene Wert ist nothing
.
Collatz-Sequenz
Die while
Schleife läuft so lange, bis die Bedingung erfüllt ist. Mit dem folgenden Code wird beispielsweise die Collatz-Sequenz aus einer bestimmten Anzahl berechnet und gedruckt:
function collatz(n)
while n ≠ 1
println(n)
n = iseven(n) ? n ÷ 2 : 3n + 1
end
println("1... and 4, 2, 1, 4, 2, 1 and so on")
end
Verwendungszweck:
julia> collatz(10)
10
5
16
8
4
2
1... and 4, 2, 1, 4, 2, 1 and so on
Es ist möglich, jede Schleife rekursiv zu schreiben, und für komplexe while
Schleifen ist manchmal die rekursive Variante klarer. In Julia haben Schleifen jedoch einige Vorteile gegenüber der Rekursion:
- Julia garantiert nicht die Beseitigung von Rückrufen, daher verwendet Rekursion zusätzlichen Speicher und kann zu Überlauffehlern führen.
- Aus demselben Grund kann eine Schleife den Overhead verringert haben und schneller laufen.
Einmal ausführen, bevor die Bedingung getestet wird
Manchmal möchte man einmal Initialisierungscode ausführen, bevor eine Bedingung getestet wird. In bestimmten anderen Sprachen hat diese Art von Schleife eine spezielle do
while
Syntax. Allerdings kann diese Syntax mit einer regelmäßigen ersetzt werden , while
Schleife und break
Aussage, so Julia hat keine spezielle do
- while
Syntax. Stattdessen schreibt man:
local name
# continue asking for input until satisfied
while true
# read user input
println("Type your name, without lowercase letters:")
name = readline()
# if there are no lowercase letters, we have our result!
!any(islower, name) && break
end
Beachten Sie, dass in manchen Situationen solche Schleifen bei Rekursion klarer sein könnten:
function getname()
println("Type your name, without lowercase letters:")
name = readline()
if any(islower, name)
getname() # this name is unacceptable; try again
else
name # this name is good, return it
end
end
Breitensuche
(Obwohl dieses Beispiel mit der in Version v0.5 eingeführten Syntax geschrieben wurde, kann es auch mit einigen Änderungen an älteren Versionen funktionieren.)
Diese Implementierung der Breitensuche (BFS) in einem mit Nachbarschaftslisten dargestellten Graphen verwendet while
Schleifen und die return
Anweisung. Die Aufgabe, die wir lösen werden, lautet wie folgt: Wir haben eine Abfolge von Menschen und eine Abfolge von Freundschaften (Freundschaften sind gegenseitig). Wir möchten den Grad der Verbindung zwischen zwei Personen bestimmen. Das heißt, wenn zwei Leute Freunde sind, werden wir 1
; Wenn einer von beiden befreundet ist, werden wir 2
zurückkehren und so weiter.
Nehmen wir zunächst an, wir haben bereits eine Adjazenzliste: ein Dict
T
auf Array{T, 1}
Dict
, wobei die Schlüssel Personen sind und die Werte alle Freunde dieser Person sind. Hier können wir Menschen mit dem von uns gewählten Typ T
; In diesem Beispiel verwenden wir Symbol
. Im BFS-Algorithmus führen wir eine Reihe von Personen, die "Besuch" machen sollen, und markieren deren Entfernung vom Ursprungsknoten.
function degree(adjlist, source, dest)
distances = Dict(source => 0)
queue = [source]
# until the queue is empty, get elements and inspect their neighbours
while !isempty(queue)
# shift the first element off the queue
current = shift!(queue)
# base case: if this is the destination, just return the distance
if current == dest
return distances[dest]
end
# go through all the neighbours
for neighbour in adjlist[current]
# if their distance is not already known...
if !haskey(distances, neighbour)
# then set the distance
distances[neighbour] = distances[current] + 1
# and put into queue for later inspection
push!(queue, neighbour)
end
end
end
# we could not find a valid path
error("$source and $dest are not connected.")
end
Nun schreiben wir eine Funktion, um eine Adjazenzliste mit einer Abfolge von Personen und einer Abfolge von (person, person)
Tupeln zu erstellen:
function makeadjlist(people, friendships)
# dictionary comprehension (with generator expression)
result = Dict(p => eltype(people)[] for p in people)
# deconstructing for; friendship is mutual
for (a, b) in friendships
push!(result[a], b)
push!(result[b], a)
end
result
end
Wir können jetzt die ursprüngliche Funktion definieren:
degree(people, friendships, source, dest) =
degree(makeadjlist(people, friendships), source, dest)
Lassen Sie uns nun unsere Funktion an einigen Daten testen.
const people = [:jean, :javert, :cosette, :gavroche, :éponine, :marius]
const friendships = [
(:jean, :cosette),
(:jean, :marius),
(:cosette, :éponine),
(:cosette, :marius),
(:gavroche, :éponine)
]
Jean ist in 0
Schritten mit sich selbst verbunden:
julia> degree(people, friendships, :jean, :jean)
0
Jean und Cosette sind Freunde und haben Grad 1
:
julia> degree(people, friendships, :jean, :cosette)
1
Jean und Gavroche sind indirekt durch Cosette und dann über Marius miteinander verbunden, so dass ihr Grad 3
beträgt:
julia> degree(people, friendships, :jean, :gavroche)
3
Javert und Marius sind über keine Kette miteinander verbunden, daher wird ein Fehler ausgegeben:
julia> degree(people, friendships, :javert, :marius)
ERROR: javert and marius are not connected.
in degree(::Dict{Symbol,Array{Symbol,1}}, ::Symbol, ::Symbol) at ./REPL[28]:27
in degree(::Array{Symbol,1}, ::Array{Tuple{Symbol,Symbol},1}, ::Symbol, ::Symbol) at ./REPL[30]:1