Buscar..


Sintaxis

  • mientras cond cuerpo; fin
  • descanso
  • continuar

Observaciones

El while de bucle no tiene un valor; aunque se puede usar en la posición de expresión, su tipo es Void y el valor obtenido no será nothing .

Secuencia de collatz

El while bucle se ejecuta su cuerpo, siempre y cuando la condición se cumple. Por ejemplo, el siguiente código calcula e imprime la secuencia de Collatz desde un número dado:

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

Uso:

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

Es posible escribir cualquier bucle de forma recursiva, y para complejos while bucles, a veces la variante recursiva es más clara. Sin embargo, en Julia, los bucles tienen algunas ventajas distintas sobre la recursión:

  • Julia no garantiza la eliminación de la llamada de cola, por lo que la recursión usa memoria adicional y puede causar errores de desbordamiento de pila.
  • Y además, por la misma razón, un bucle puede tener una sobrecarga reducida y correr más rápido.

Ejecutar una vez antes de probar la condición

A veces, uno quiere ejecutar algún código de inicialización una vez antes de probar una condición. En algunos otros idiomas, este tipo de bucle tiene una sintaxis especial de do - while . Sin embargo, esta sintaxis se puede sustituir por un habitual while bucle y break declaración, por lo que Julia no se han especializado do - while la sintaxis. En su lugar, uno escribe:

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

Tenga en cuenta que en algunas situaciones, tales bucles podrían ser más claros con la recursión:

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

Búsqueda de amplitud

0.5.0

(Aunque este ejemplo está escrito utilizando la sintaxis introducida en la versión v0.5, también puede funcionar con algunas modificaciones en versiones anteriores).

Esta aplicación de búsqueda en anchura (BFS) en un gráfico representado con listas de adyacencia utiliza while bucles y el return comunicado. La tarea que resolveremos es la siguiente: tenemos una secuencia de personas y una secuencia de amistades (las amistades son mutuas). Queremos determinar el grado de conexión entre dos personas. Es decir, si dos personas son amigas, devolveremos 1 ; si uno es amigo de un amigo del otro, regresaremos 2 , y así sucesivamente.

Primero, supongamos que ya tenemos una lista de adyacencia: un Dict mapeo T a Array{T, 1} , donde las claves son personas y los valores son todos los amigos de esa persona. Aquí podemos representar a personas con cualquier tipo de T que escojamos; En este ejemplo, usaremos Symbol . En el algoritmo BFS, mantenemos una cola de personas para "visitar", y marcamos su distancia desde el nodo de origen.

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

Ahora, escribiremos una función para construir una lista de adyacencia dada una secuencia de personas y una secuencia de tuplas (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

Ahora podemos definir la función original:

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

Ahora probemos nuestra función en algunos datos.

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

Jean está conectado a sí mismo en 0 pasos:

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

Jean y Cosette son amigos, y por eso tienen el grado 1 :

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

Jean y Gavroche están conectados indirectamente a través de Cosette y luego a Marius, por lo que su grado es 3 :

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

Javert y Marius no están conectados a través de ninguna cadena, por lo que se produce un error:

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow