Julia Language
while 루프
수색…
통사론
- 동안 cond; 신체; 종료
- 단절
- 잇다
비고
while
루프에는 값이 없습니다. 표현식 위치에서 사용할 수는 있지만 형식은 Void
이며 얻은 값은 nothing
.
Collatz 시퀀스
while
루프는 조건이 충족되는 한 본체를 실행합니다. 예를 들어, 다음 코드는 주어진 숫자에서 Collatz 시퀀스 를 계산하고 출력합니다 :
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
너비 우선 검색
(이 예제는 v0.5 버전에서 도입 된 구문을 사용하여 작성되었지만 이전 버전에서도 약간의 수정 작업이 가능합니다.)
인접 목록으로 표현 된 그래프에서의 너비 우선 탐색 (BFS) 구현은 while
루프와 return
문을 사용합니다. 우리가 해결할 과제는 다음과 같습니다 : 우리는 일련의 사람들과 우정의 순서 (우정은 상호 적입니다)를 가지고 있습니다. 우리는 두 사람 사이의 연결 정도를 결정하려고합니다. 즉, 두 사람이 친구 인 경우 1
을 반환합니다. 친구가 다른 친구의 친구라면 우리는 2
를 반환 할 것입니다.
첫째, 우리는 이미 인접리스트가 가정하자하십시오 Dict
매핑 T
에 Array{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)
]
Jean은 0
단계로 자신과 연결되어 있습니다.
julia> degree(people, friendships, :jean, :jean)
0
Jean과 Cosette는 친구이고 학위도 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