Recherche…


Syntaxe

  • tandis que cond; corps; fin
  • Pause
  • continuer

Remarques

Le while en boucle ne possède pas de valeur; Bien qu'il puisse être utilisé dans une position d'expression, son type est Void et la valeur obtenue ne sera nothing .

Séquence Collatz

Le while en boucle court son corps aussi longtemps que la condition est. Par exemple, le code suivant calcule et imprime la séquence Collatz à partir d'un nombre donné:

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

Usage:

julia> collatz(10)
10
5
16
8
4
2
1... and 4, 2, 1, 4, 2, 1 and so on

Il est possible d'écrire une boucle récursive, et complexe while boucles, parfois la variante récursive est plus claire. Cependant, chez Julia, les boucles présentent des avantages distincts par rapport à la récursivité:

  • Julia ne garantit pas l'élimination des appels de queue, la récursivité utilise donc de la mémoire supplémentaire et peut provoquer des erreurs de dépassement de capacité de la pile.
  • De plus, pour la même raison, une boucle peut avoir un temps de traitement réduit et s'exécuter plus rapidement.

Exécuter une fois avant de tester la condition

Parfois, on veut exécuter du code d'initialisation une fois avant de tester une condition. Dans certaines autres langues, ce genre de boucle a spécial do - while la syntaxe. Cependant, cette syntaxe peut être remplacée par une instruction while boucle et break , de sorte que Julia n'a pas de syntaxe do - while spécialisée. Au lieu de cela, on écrit:

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

Notez que dans certaines situations, de telles boucles pourraient être plus claires avec la récursivité:

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

Recherche en largeur

0.5.0

(Bien que cet exemple soit écrit en utilisant la syntaxe introduite dans la version v0.5, il peut également fonctionner avec peu de modifications sur les anciennes versions.)

Cette implémentation de la recherche en largeur (BFS) sur un graphique représenté avec des listes de contiguïté utilise les boucles while et la déclaration de return . La tâche que nous allons résoudre est la suivante: nous avons une séquence de personnes et une séquence d’amitiés (les amitiés sont mutuelles). Nous voulons déterminer le degré de connexion entre deux personnes. Autrement dit, si deux personnes sont amis, nous reviendrons à 1 ; si l'un est un ami d'un ami de l'autre, nous reviendrons à 2 , et ainsi de suite.

Tout d'abord, supposons que nous ayons déjà une liste d'adjacence: un Dict mapping T to Array{T, 1} , où les clés sont des personnes et les valeurs sont toutes les amies de cette personne. Ici, nous pouvons représenter des personnes avec le type T choisi. dans cet exemple, nous utiliserons Symbol . Dans l'algorithme BFS, nous conservons une file d'attente de personnes pour «visiter» et marquer leur distance par rapport au nœud d'origine.

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

Maintenant, nous allons écrire une fonction pour construire une liste d'adjacence à partir d'une séquence de personnes, et une séquence de tuples (person, person) :

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

Nous pouvons maintenant définir la fonction d'origine:

degree(people, friendships, source, dest) =
    degree(makeadjlist(people, friendships), source, dest)

Maintenant, testons notre fonction sur certaines données.

const people = [:jean, :javert, :cosette, :gavroche, :éponine, :marius]
const friendships = [
    (:jean, :cosette),
    (:jean, :marius),
    (:cosette, :éponine),
    (:cosette, :marius),
    (:gavroche, :éponine)
]

Jean est connecté en 0 étapes:

julia> degree(people, friendships, :jean, :jean)
0

Jean et Cosette sont amis et ont donc un diplôme 1 :

julia> degree(people, friendships, :jean, :cosette)
1

Jean et Gavroche sont connectés indirectement via Cosette puis Marius, leur diplôme est donc 3 :

julia> degree(people, friendships, :jean, :gavroche)
3

Javert et Marius ne sont connectés via aucune chaîne, une erreur est donc générée:

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


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow