サーチ…


構文

  • 一方、cond。体;終わり
  • ブレーク
  • 持続する

備考

whileループには値はありません。式の位置で使用することはできますが、その型はVoidあり、得られた値はnothingありnothing

Collat​​zシーケンス

whileループは、条件が成立する限り、その本体を実行します。たとえば、次のコードは、指定された数値からCollat​​zシーケンスを計算して出力します

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

使用法:

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

任意のループを再帰的に記述することは可能であり、複雑なwhileループに対しては、再帰的な変形がより明確になることがあります。しかし、Juliaでは、ループは再帰よりもいくつかの明確な利点があります。

  • Juliaはテールコールの消去を保証しません。したがって、再帰で追加のメモリが使用され、スタックオーバーフローエラーが発生する可能性があります。
  • さらに、同じ理由で、ループがオーバーヘッドを減らし、より速く実行できるようになります。

テスト条件の前に一度実行する

場合によっては、条件をテストする前に初期化コードを一度実行したい場合もあります。ある種の他の言語では、この種のループには特別なdo - while構文がwhileます。ただし、この構文は通常のwhileループとbreak文に置き換えることができます。そのため、Juliaには特別なdo - while構文はありません。代わりに、

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

状況によっては、このようなループが再帰でより明確になることがあります。

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

幅優先探索

0.5.0

(この例は、バージョンv0.5で導入された構文を使用して書かれていますが、古いバージョンでもほとんど変更されません)。

隣接リストで表されるグラフの幅優先検索 (BFS)のこの実装は、 whileループとreturnステートメントを使用whileます。私たちが解決する課題は、一連の人と一連の友情(友情は相互にあります)です。我々は2人の人のつながりの程度を判断したい。つまり、2人が友人であれば1を返します。もし誰かが他の人の友人であれば、 2を返します。

まず、隣接リストが既にあると仮定しましょう: Dict TArray{T, 1}にマッピングします。ここで、キーは人であり、値はその人のすべての友人です。ここでは、タイプTを選んだ人を表すことができます。この例では、 Symbolを使用します。 BFSアルゴリズムでは、人々の待ち行列を「訪問」し、起点ノードからの距離をマークする。

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

今度は、一連の人と一連の(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

これで元の関数を定義できます。

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

さて、いくつかのデータに対して私たちの関数をテストしましょう。

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

ジーンは0ステップで自分自身に接続されています:

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

ジーンとコゼットは友達であり、学位1ます:

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

JeanとGavrocheはCosetteとMariusを介して間接的に接続されているので、その程度は3

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

JavertとMariusはチェーンを介して接続されていないので、エラーが発生します。

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
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow