Sorting and Related Functions
줄리아는 이미 정렬된 값 배열을 정렬하고 상호작용하는 데 있어 광범위하고 유연한 API를 제공합니다. 기본적으로 줄리아는 합리적인 알고리즘을 선택하고 오름차순으로 정렬합니다:
julia> sort([2,3,1])
3-element Vector{Int64}:
1
2
3
역순으로 정렬할 수도 있습니다:
julia> sort([2,3,1], rev=true)
3-element Vector{Int64}:
3
2
1
sort
는 입력을 변경하지 않고 정렬된 복사본을 생성합니다. 기존 배열을 변형하려면 "bang" 버전의 정렬 함수를 사용하세요:
julia> a = [2,3,1];
julia> sort!(a);
julia> a
3-element Vector{Int64}:
1
2
3
배열을 직접 정렬하는 대신, 배열을 정렬된 순서로 배치하는 배열의 인덱스의 순열을 계산할 수 있습니다:
julia> v = randn(5)
5-element Array{Float64,1}:
0.297288
0.382396
-0.597634
-0.0104452
-0.839027
julia> p = sortperm(v)
5-element Array{Int64,1}:
5
3
4
1
2
julia> v[p]
5-element Array{Float64,1}:
-0.839027
-0.597634
-0.0104452
0.297288
0.382396
배열은 값의 임의 변환에 따라 정렬될 수 있습니다:
julia> sort(v, by=abs)
5-element Array{Float64,1}:
-0.0104452
0.297288
0.382396
-0.597634
-0.839027
또는 변환에 의해 역순으로:
julia> sort(v, by=abs, rev=true)
5-element Array{Float64,1}:
-0.839027
-0.597634
0.382396
0.297288
-0.0104452
필요한 경우, 정렬 알고리즘을 선택할 수 있습니다:
julia> sort(v, alg=InsertionSort)
5-element Array{Float64,1}:
-0.839027
-0.597634
-0.0104452
0.297288
0.382396
모든 정렬 및 순서 관련 함수는 조작할 값에 대해 strict weak order를 정의하는 "작다" 관계에 의존합니다. 기본적으로 isless
함수가 호출되지만, 관계는 lt
키워드를 통해 지정할 수 있으며, 이 함수는 두 배열 요소를 받아들이고 첫 번째 인수가 두 번째 인수보다 "작다"면 true
를 반환합니다. 더 많은 정보는 sort!
및 Alternate Orderings를 참조하십시오.
Sorting Functions
Base.sort!
— Functionsort!(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)
벡터 v
를 제자리에서 정렬합니다. 기본적으로 안정적인 알고리즘이 사용되며, 동등하게 비교되는 요소의 순서가 유지됩니다. 특정 알고리즘은 alg
키워드를 통해 선택할 수 있습니다(사용 가능한 알고리즘에 대한 내용은 Sorting Algorithms를 참조하십시오).
요소는 먼저 by
함수로 변환된 후, lt
함수 또는 order
에 따라 비교됩니다. 마지막으로, rev=true
인 경우 결과 순서가 반전됩니다(이는 전방 안정성을 유지합니다: 동등하게 비교되는 요소는 반전되지 않습니다). 현재 구현은 각 비교 전에 by
변환을 적용하며, 요소당 한 번만 적용되지 않습니다.
isless
가 아닌 lt
와 Base.Order.Forward
또는 Base.Order.Reverse
가 아닌 order
를 함께 사용하는 것은 허용되지 않습니다. 그렇지 않으면 모든 옵션은 독립적이며 가능한 모든 조합으로 함께 사용할 수 있습니다. order
는 "by" 변환을 포함할 수 있으며, 이 경우 by
키워드로 정의된 후에 적용됩니다. order
값에 대한 자세한 내용은 Alternate Orderings 문서를 참조하십시오.
두 요소 간의 관계는 다음과 같이 정의됩니다(여기서 rev=true
일 때 "less"와 "greater"가 교환됩니다):
x
는y
보다 작으면lt(by(x), by(y))
(또는Base.Order.lt(order, by(x), by(y))
)가 true를 반환합니다.x
는y
보다 크면y
가x
보다 작습니다.x
와y
는 서로 작지 않으면 동등합니다("비교 불가능"은 때때로 "동등"의 동의어로 사용됩니다).
sort!
의 결과는 모든 요소가 이전 요소보다 크거나 동등하다는 의미에서 정렬됩니다.
lt
함수는 엄격한 약한 순서를 정의해야 하며, 즉 다음과 같아야 합니다.
- 비반사적:
lt(x, x)
는 항상false
를 반환해야 합니다. - 비대칭:
lt(x, y)
가 true를 반환하면lt(y, x)
는 false를 반환해야 합니다. - 추이적:
lt(x, y) && lt(y, z)
는lt(x, z)
를 의미합니다. - 동등성에서의 추이적:
!lt(x, y) && !lt(y, x)
와!lt(y, z) && !lt(z, y)
가 함께!lt(x, z) && !lt(z, x)
를 의미합니다. 즉,x
와y
가 동등하고y
와z
가 동등하면x
와z
도 동등해야 합니다.
예를 들어 <
는 Int
값에 대한 유효한 lt
함수이지만 ≤
는 그렇지 않습니다: 비반사성을 위반합니다. Float64
값의 경우 <
조차도 유효하지 않습니다. 이는 네 번째 조건을 위반하기 때문입니다: 1.0
과 NaN
은 동등하고 NaN
과 2.0
도 동등하지만 1.0
과 2.0
은 동등하지 않습니다.
또한 sort
, sortperm
, sortslices
, partialsort!
, partialsortperm
, issorted
, searchsorted
, insorted
, Base.Order.ord
를 참조하십시오.
예제
julia> v = [3, 1, 2]; sort!(v); v
3-element Vector{Int64}:
1
2
3
julia> v = [3, 1, 2]; sort!(v, rev = true); v
3-element Vector{Int64}:
3
2
1
julia> v = [(1, "c"), (3, "a"), (2, "b")]; sort!(v, by = x -> x[1]); v
3-element Vector{Tuple{Int64, String}}:
(1, "c")
(2, "b")
(3, "a")
julia> v = [(1, "c"), (3, "a"), (2, "b")]; sort!(v, by = x -> x[2]); v
3-element Vector{Tuple{Int64, String}}:
(3, "a")
(2, "b")
(1, "c")
julia> sort(0:3, by=x->x-2, order=Base.Order.By(abs)) # same as sort(0:3, by=abs(x->x-2))
4-element Vector{Int64}:
2
1
3
0
julia> sort([2, NaN, 1, NaN, 3]) # correct sort with default lt=isless
5-element Vector{Float64}:
1.0
2.0
3.0
NaN
NaN
julia> sort([2, NaN, 1, NaN, 3], lt=<) # wrong sort due to invalid lt. This behavior is undefined.
5-element Vector{Float64}:
2.0
NaN
1.0
NaN
3.0
sort!(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)
다차원 배열 A
를 차원 dims
에 따라 정렬합니다. 가능한 키워드 인수에 대한 설명은 sort!
의 일차원 버전을 참조하십시오.
배열의 슬라이스를 정렬하려면 sortslices
를 참조하십시오.
이 함수는 최소한 Julia 1.1이 필요합니다.
예제
julia> A = [4 3; 1 2]
2×2 Matrix{Int64}:
4 3
1 2
julia> sort!(A, dims = 1); A
2×2 Matrix{Int64}:
1 2
4 3
julia> sort!(A, dims = 2); A
2×2 Matrix{Int64}:
1 2
3 4
Base.sort
— Functionsort(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)
sort!
의 변형으로, v
를 수정하지 않고 정렬된 복사본을 반환합니다.
예제
julia> v = [3, 1, 2];
julia> sort(v)
3-element Vector{Int64}:
1
2
3
julia> v
3-element Vector{Int64}:
3
1
2
sort(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)
주어진 차원에 따라 다차원 배열 A
를 정렬합니다. 가능한 키워드 인수에 대한 설명은 sort!
를 참조하십시오.
배열의 슬라이스를 정렬하려면 sortslices
를 참조하십시오.
예제
julia> A = [4 3; 1 2]
2×2 Matrix{Int64}:
4 3
1 2
julia> sort(A, dims = 1)
2×2 Matrix{Int64}:
1 2
4 3
julia> sort(A, dims = 2)
2×2 Matrix{Int64}:
3 4
1 2
Base.sortperm
— Functionsortperm(A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])
주어진 차원에서 A[I]
를 정렬된 순서로 배치하는 순열 벡터 또는 배열 I
를 반환합니다. A
가 여러 차원을 가지는 경우, dims
키워드 인수를 지정해야 합니다. 순서는 sort!
와 동일한 키워드를 사용하여 지정됩니다. 정렬 알고리즘이 불안정하더라도 순열은 안정적일 것이며, 동일한 요소의 인덱스는 오름차순으로 나타납니다.
또한 sortperm!
, partialsortperm
, invperm
, indexin
도 참조하십시오. 배열의 슬라이스를 정렬하려면 sortslices
를 참조하십시오.
dims
를 수용하는 메서드는 최소한 Julia 1.9가 필요합니다.
예제
julia> v = [3, 1, 2];
julia> p = sortperm(v)
3-element Vector{Int64}:
2
3
1
julia> v[p]
3-element Vector{Int64}:
1
2
3
julia> A = [8 7; 5 6]
2×2 Matrix{Int64}:
8 7
5 6
julia> sortperm(A, dims = 1)
2×2 Matrix{Int64}:
2 4
1 3
julia> sortperm(A, dims = 2)
2×2 Matrix{Int64}:
3 1
2 4
Base.Sort.InsertionSort
— Constant삽입 정렬
삽입 정렬 알고리즘을 사용합니다.
삽입 정렬은 컬렉션을 한 번에 하나의 요소씩 탐색하며, 각 요소를 출력 벡터의 올바른 정렬된 위치에 삽입합니다.
특징:
- 안정적: 동일하게 비교되는 요소의 순서를 유지합니다.
(예: 대소문자를 무시하는 문자 정렬에서 "a"와 "A").
- 제자리에서 메모리 사용.
- 2차 성능 요소 수에 따라:
작은 컬렉션에 적합하지만 큰 컬렉션에는 사용해서는 안 됩니다.
Base.Sort.MergeSort
— Constant병합 정렬
정렬 함수가 병합 정렬 알고리즘을 사용해야 함을 나타냅니다. 병합 정렬은 컬렉션을 하위 컬렉션으로 나누고, 각 단계에서 각 하위 컬렉션을 정렬하면서 반복적으로 병합하여 전체 컬렉션이 정렬된 형태로 재조합될 때까지 진행합니다.
특징:
- 안정적: 동등하게 비교되는 요소의 순서를 보존합니다 (예: 대소문자를 무시하는 문자 정렬에서 "a"와 "A").
- 메모리에서 제자리 정렬이 아님.
- 분할 정복 정렬 전략.
- 대규모 컬렉션에 대한 좋은 성능을 보이지만 일반적으로
QuickSort
만큼 빠르지는 않습니다.
Base.Sort.QuickSort
— Constant퀵 정렬
정렬 함수가 안정적이지 않은 퀵 정렬 알고리즘을 사용해야 함을 나타냅니다.
특징:
- 안정적이지 않음: 동등하게 비교되는 요소의 순서를 보존하지 않음 (예: 대소문자를 무시하는 문자 정렬에서 "a"와 "A").
- 제자리에서 메모리 사용.
- 분할 정복:
MergeSort
와 유사한 정렬 전략. - 대규모 컬렉션에 대한 좋은 성능.
Base.Sort.PartialQuickSort
— TypePartialQuickSort{T <: Union{Integer,OrdinalRange}}
정렬 함수가 부분 퀵 정렬 알고리즘을 사용해야 함을 나타냅니다. PartialQuickSort(k)
는 QuickSort
와 같지만, v
가 완전히 정렬되었을 때 v[k]
에 위치할 요소만 찾아서 정렬하는 데 필요합니다.
특징:
- 안정적이지 않음: 동등하게 비교되는 요소의 순서를 보존하지 않습니다 (예: 대소문자를 무시하는 문자 정렬에서 "a"와 "A").
- 제자리에서 메모리 내에서 수행됩니다.
- 분할 정복:
MergeSort
와 유사한 정렬 전략입니다.
PartialQuickSort(k)
는 전체 배열을 반드시 정렬하지는 않습니다. 예를 들어,
julia> x = rand(100);
julia> k = 50:100;
julia> s1 = sort(x; alg=QuickSort);
julia> s2 = sort(x; alg=PartialQuickSort(k));
julia> map(issorted, (s1, s2))
(true, false)
julia> map(x->issorted(x[k]), (s1, s2))
(true, true)
julia> s1[k] == s2[k]
true
Base.Sort.sortperm!
— Functionsortperm!(ix, A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])
sortperm
와 유사하지만, A
와 동일한 axes
를 가진 미리 할당된 인덱스 벡터 또는 배열 ix
를 허용합니다. ix
는 LinearIndices(A)
의 값을 포함하도록 초기화됩니다.
!!! 경고 변형된 인수가 다른 인수와 메모리를 공유할 경우 동작이 예기치 않게 될 수 있습니다.
!!! 호환성 "Julia 1.9" dims
를 허용하는 메서드는 최소한 Julia 1.9가 필요합니다.
예제
julia> v = [3, 1, 2]; p = zeros(Int, 3);
julia> sortperm!(p, v); p
3-element Vector{Int64}:
2
3
1
julia> v[p]
3-element Vector{Int64}:
1
2
3
julia> A = [8 7; 5 6]; p = zeros(Int,2, 2);
julia> sortperm!(p, A; dims=1); p
2×2 Matrix{Int64}:
2 4
1 3
julia> sortperm!(p, A; dims=2); p
2×2 Matrix{Int64}:
3 1
2 4
Base.sortslices
— Functionsortslices(A; dims, alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)
배열 A
의 슬라이스를 정렬합니다. 필수 키워드 인수 dims
는 정수 또는 정수의 튜플이어야 합니다. 이는 슬라이스가 정렬되는 차원(dimension)을 지정합니다.
예를 들어, A
가 행렬인 경우, dims=1
은 행을 정렬하고, dims=2
는 열을 정렬합니다. 1차원 슬라이스에 대한 기본 비교 함수는 사전식으로 정렬합니다.
나머지 키워드 인수에 대한 내용은 sort!
문서를 참조하십시오.
예제
julia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1) # 행 정렬
3×3 Matrix{Int64}:
-1 6 4
7 3 5
9 -2 8
julia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1, lt=(x,y)->isless(x[2],y[2]))
3×3 Matrix{Int64}:
9 -2 8
7 3 5
-1 6 4
julia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1, rev=true)
3×3 Matrix{Int64}:
9 -2 8
7 3 5
-1 6 4
julia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2) # 열 정렬
3×3 Matrix{Int64}:
3 5 7
-1 -4 6
-2 8 9
julia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2, alg=InsertionSort, lt=(x,y)->isless(x[2],y[2]))
3×3 Matrix{Int64}:
5 3 7
-4 -1 6
8 -2 9
julia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2, rev=true)
3×3 Matrix{Int64}:
7 5 3
6 -4 -1
9 8 -2
고차원
sortslices
는 고차원으로 자연스럽게 확장됩니다. 예를 들어, A
가 2x2x2 배열인 경우, sortslices(A, dims=3)
는 3차원 내에서 슬라이스를 정렬하며, 2x2 슬라이스 A[:, :, 1]
과 A[:, :, 2]
를 비교 함수에 전달합니다. 고차원 슬라이스에는 기본 순서가 없지만, by
또는 lt
키워드 인수를 사용하여 그러한 순서를 지정할 수 있습니다.
dims
가 튜플인 경우, dims
의 차원 순서가 중요하며 슬라이스의 선형 순서를 지정합니다. 예를 들어, A
가 3차원이고 dims
가 (1, 2)
인 경우, 첫 번째 두 차원의 순서가 재배열되어 나머지 세 번째 차원의 슬라이스가 정렬됩니다. 대신 dims
가 (2, 1)
인 경우, 동일한 슬라이스가 선택되지만 결과 순서는 행 우선(row-major)으로 변경됩니다.
고차원 예제
julia> A = [4 3; 2 1 ;;; 'A' 'B'; 'C' 'D']
2×2×2 Array{Any, 3}:
[:, :, 1] =
4 3
2 1
[:, :, 2] =
'A' 'B'
'C' 'D'
julia> sortslices(A, dims=(1,2))
2×2×2 Array{Any, 3}:
[:, :, 1] =
1 3
2 4
[:, :, 2] =
'D' 'B'
'C' 'A'
julia> sortslices(A, dims=(2,1))
2×2×2 Array{Any, 3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
'D' 'C'
'B' 'A'
julia> sortslices(reshape([5; 4; 3; 2; 1], (1,1,5)), dims=3, by=x->x[1,1])
1×1×5 Array{Int64, 3}:
[:, :, 1] =
1
[:, :, 2] =
2
[:, :, 3] =
3
[:, :, 4] =
4
[:, :, 5] =
5
Order-Related Functions
Base.issorted
— Functionissorted(v, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)
컬렉션이 정렬된 순서인지 테스트합니다. 키워드는 sort!
문서에 설명된 대로 어떤 순서가 정렬된 것으로 간주되는지를 수정합니다.
예제
julia> issorted([1, 2, 3])
true
julia> issorted([(1, "b"), (2, "a")], by = x -> x[1])
true
julia> issorted([(1, "b"), (2, "a")], by = x -> x[2])
false
julia> issorted([(1, "b"), (2, "a")], by = x -> x[2], rev=true)
true
julia> issorted([1, 2, -2, 3], by=abs)
true
Base.Sort.searchsorted
— Functionsearchsorted(v, x; by=identity, lt=isless, rev=false)
값이 x
와 동일한 v
의 인덱스 범위를 반환하거나, v
에 x
와 동일한 값이 없을 경우 삽입 지점에 위치한 빈 범위를 반환합니다. 벡터 v
는 키워드에 의해 정의된 순서에 따라 정렬되어 있어야 합니다. 키워드의 의미와 동등성의 정의에 대해서는 sort!
를 참조하십시오. by
함수는 검색된 값 x
와 v
의 값 모두에 적용됩니다.
범위는 일반적으로 이진 검색을 사용하여 찾지만, 일부 입력에 대해 최적화된 구현이 있습니다.
또한 참조: searchsortedfirst
, sort!
, insorted
, findall
.
예제
julia> searchsorted([1, 2, 4, 5, 5, 7], 4) # 단일 일치
3:3
julia> searchsorted([1, 2, 4, 5, 5, 7], 5) # 다중 일치
4:5
julia> searchsorted([1, 2, 4, 5, 5, 7], 3) # 일치 없음, 중간에 삽입
3:2
julia> searchsorted([1, 2, 4, 5, 5, 7], 9) # 일치 없음, 끝에 삽입
7:6
julia> searchsorted([1, 2, 4, 5, 5, 7], 0) # 일치 없음, 시작에 삽입
1:0
julia> searchsorted([1=>"one", 2=>"two", 2=>"two", 4=>"four"], 2=>"two", by=first) # 쌍의 키 비교
2:3
Base.Sort.searchsortedfirst
— Functionsearchsortedfirst(v, x; by=identity, lt=isless, rev=false)
v
에서 x
보다 앞서 정렬되지 않은 첫 번째 값의 인덱스를 반환합니다. 만약 v
의 모든 값이 x
보다 앞서 정렬되어 있다면, lastindex(v) + 1
을 반환합니다.
벡터 v
는 키워드에 의해 정의된 순서에 따라 정렬되어 있어야 합니다. 반환된 인덱스에 x
를 insert!
하면 정렬된 순서를 유지합니다. 키워드의 의미와 사용법에 대해서는 sort!
를 참조하세요. by
함수는 검색된 값 x
와 v
의 값 모두에 적용됩니다.
인덱스는 일반적으로 이진 검색을 사용하여 찾지만, 일부 입력에 대해 최적화된 구현이 있습니다.
또한: searchsortedlast
, searchsorted
, findfirst
.
예제
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 4) # 단일 일치
3
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 5) # 다중 일치
4
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 3) # 일치 없음, 중간에 삽입
3
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 9) # 일치 없음, 끝에 삽입
7
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 0) # 일치 없음, 시작에 삽입
1
julia> searchsortedfirst([1=>"one", 2=>"two", 4=>"four"], 3=>"three", by=first) # 쌍의 키 비교
3
Base.Sort.searchsortedlast
— Functionsearchsortedlast(v, x; by=identity, lt=isless, rev=false)
x
보다 정렬되지 않은 v
의 마지막 값의 인덱스를 반환합니다. 만약 v
의 모든 값이 x
보다 정렬되어 있다면, firstindex(v) - 1
을 반환합니다.
벡터 v
는 키워드에 의해 정의된 순서에 따라 정렬되어 있어야 합니다. 반환된 인덱스 바로 뒤에 x
를 insert!
하면 정렬된 순서를 유지합니다. 키워드의 의미와 사용법에 대해서는 sort!
를 참조하세요. by
함수는 검색된 값 x
와 v
의 값 모두에 적용됩니다.
인덱스는 일반적으로 이진 검색을 사용하여 찾지만, 일부 입력에 대해 최적화된 구현이 있습니다.
예제
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 4) # 단일 일치
3
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 5) # 다중 일치
5
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 3) # 일치 없음, 중간에 삽입
2
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 9) # 일치 없음, 끝에 삽입
6
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 0) # 일치 없음, 시작에 삽입
0
julia> searchsortedlast([1=>"one", 2=>"two", 4=>"four"], 3=>"three", by=first) # 쌍의 키 비교
2
Base.Sort.insorted
— Functioninsorted(x, v; by=identity, lt=isless, rev=false) -> Bool
벡터 v
에 x
와 동등한 값이 포함되어 있는지 확인합니다. 벡터 v
는 키워드에 의해 정의된 순서에 따라 정렬되어 있어야 합니다. 키워드의 의미와 동등성의 정의에 대해서는 sort!
를 참조하십시오. by
함수는 검색된 값 x
와 v
의 값 모두에 적용됩니다.
검사는 일반적으로 이진 검색을 사용하여 수행되지만, 일부 입력에 대해 최적화된 구현이 있습니다.
또한 in
를 참조하십시오.
예제
julia> insorted(4, [1, 2, 4, 5, 5, 7]) # 단일 일치
true
julia> insorted(5, [1, 2, 4, 5, 5, 7]) # 다중 일치
true
julia> insorted(3, [1, 2, 4, 5, 5, 7]) # 일치 없음
false
julia> insorted(9, [1, 2, 4, 5, 5, 7]) # 일치 없음
false
julia> insorted(0, [1, 2, 4, 5, 5, 7]) # 일치 없음
false
julia> insorted(2=>"TWO", [1=>"one", 2=>"two", 4=>"four"], by=first) # 쌍의 키 비교
true
insorted
는 Julia 1.6에 추가되었습니다.
Base.Sort.partialsort!
— Functionpartialsort!(v, k; by=identity, lt=isless, rev=false)
벡터 v
를 제자리에서 부분 정렬하여 인덱스 k
(또는 k
가 범위인 경우 인접한 값의 범위)에 있는 값이 배열이 완전히 정렬되었을 때 나타날 위치에 오도록 합니다. k
가 단일 인덱스인 경우 해당 값이 반환되고, k
가 범위인 경우 해당 인덱스의 값 배열이 반환됩니다. partialsort!
는 입력 배열을 완전히 정렬하지 않을 수 있습니다.
키워드 인수에 대한 내용은 sort!
문서를 참조하세요.
예제
julia> a = [1, 2, 4, 3, 4]
5-element Vector{Int64}:
1
2
4
3
4
julia> partialsort!(a, 4)
4
julia> a
5-element Vector{Int64}:
1
2
3
4
4
julia> a = [1, 2, 4, 3, 4]
5-element Vector{Int64}:
1
2
4
3
4
julia> partialsort!(a, 4, rev=true)
2
julia> a
5-element Vector{Int64}:
4
4
3
2
1
Base.Sort.partialsort
— Functionpartialsort(v, k, by=identity, lt=isless, rev=false)
partialsort!
의 변형으로, v
를 부분 정렬하기 전에 복사하여 partialsort!
와 동일한 결과를 반환하지만 v
는 수정하지 않습니다.
Base.Sort.partialsortperm
— Functionpartialsortperm(v, k; by=identity, lt=isless, rev=false)
벡터 v
의 부분 순열 I
를 반환하여, v[I]
가 인덱스 k
에서 v
의 완전히 정렬된 버전의 값을 반환하도록 합니다. k
가 범위인 경우 인덱스의 벡터가 반환되고, k
가 정수인 경우 단일 인덱스가 반환됩니다. 순서는 sort!
와 동일한 키워드를 사용하여 지정됩니다. 이 순열은 안정적이며, 동일한 요소의 인덱스는 오름차순으로 나타납니다.
이 함수는 sortperm(...)[k]
를 호출하는 것과 동등하지만, 더 효율적입니다.
예제
julia> v = [3, 1, 2, 1];
julia> v[partialsortperm(v, 1)]
1
julia> p = partialsortperm(v, 1:3)
3-element view(::Vector{Int64}, 1:3) with eltype Int64:
2
4
3
julia> v[p]
3-element Vector{Int64}:
1
1
2
Base.Sort.partialsortperm!
— Functionpartialsortperm!(ix, v, k; by=identity, lt=isless, rev=false)
partialsortperm
와 유사하지만, v
와 동일한 크기의 미리 할당된 인덱스 벡터 ix
를 받아들이며, 이는 v
의 인덱스(순열)를 저장하는 데 사용됩니다.
ix
는 v
의 인덱스를 포함하도록 초기화됩니다.
(일반적으로 v
의 인덱스는 1:length(v)
이지만, v
가 OffsetArray
와 같이 비기본 인덱스를 가진 대체 배열 유형인 경우, ix
는 동일한 인덱스를 공유해야 합니다.)
반환 시, ix
는 정렬된 위치에 k
의 인덱스를 가지도록 보장되며, 다음과 같은 관계가 성립합니다.
partialsortperm!(ix, v, k);
v[ix[k]] == partialsort(v, k)
반환 값은 k
가 정수인 경우 ix
의 k
번째 요소이며, k
가 범위인 경우 ix
에 대한 뷰입니다.
!!! 경고 변형된 인수가 다른 인수와 메모리를 공유할 경우 동작이 예기치 않게 될 수 있습니다.
예제
julia> v = [3, 1, 2, 1];
julia> ix = Vector{Int}(undef, 4);
julia> partialsortperm!(ix, v, 1)
2
julia> ix = [1:4;];
julia> partialsortperm!(ix, v, 2:3)
2-element view(::Vector{Int64}, 2:3) with eltype Int64:
4
3
```
Sorting Algorithms
현재 기본 Julia에서 공개적으로 사용할 수 있는 정렬 알고리즘은 네 가지입니다:
기본적으로 sort
함수 패밀리는 대부분의 입력에 대해 빠른 안정 정렬 알고리즘을 사용합니다. 정확한 알고리즘 선택은 향후 성능 개선을 허용하기 위한 구현 세부 사항입니다. 현재는 입력 유형, 크기 및 구성에 따라 RadixSort
, ScratchQuickSort
, InsertionSort
및 CountingSort
의 하이브리드가 사용됩니다. 구현 세부 사항은 변경될 수 있지만 현재 ??Base.DEFAULT_STABLE
의 확장 도움말과 그곳에 나열된 내부 정렬 알고리즘의 docstring에서 확인할 수 있습니다.
alg
키워드를 사용하여 선호하는 알고리즘을 명시적으로 지정할 수 있습니다 (예: sort!(v, alg=PartialQuickSort(10:20))
) 또는 Base.Sort.defalg
함수에 특수화된 메서드를 추가하여 사용자 정의 유형에 대한 기본 정렬 알고리즘을 재구성할 수 있습니다. 예를 들어, InlineStrings.jl는 다음 메서드를 정의합니다:
Base.Sort.defalg(::AbstractArray{<:Union{SmallInlineStrings, Missing}}) = InlineStringSort
기본 정렬 알고리즘(Base.Sort.defalg
에서 반환됨)은 Julia 1.9부터 안정성이 보장됩니다. 이전 버전에서는 숫자 배열을 정렬할 때 불안정한 엣지 케이스가 있었습니다.
Alternate Orderings
기본적으로, sort
, searchsorted
및 관련 함수는 두 요소를 비교하여 어떤 것이 먼저 와야 하는지를 결정하기 위해 isless
를 사용합니다. Base.Order.Ordering
추상 유형은 동일한 요소 집합에 대해 대체 정렬을 정의하는 메커니즘을 제공합니다: sort!
와 같은 정렬 함수를 호출할 때, order
라는 키워드 인수와 함께 Ordering
의 인스턴스를 제공할 수 있습니다.
Ordering
의 인스턴스는 Base.Order.lt
함수에 의해 순서를 정의하며, 이는 isless
의 일반화로 작동합니다. 이 함수의 사용자 정의 Ordering
에 대한 동작은 strict weak order의 모든 조건을 충족해야 합니다. 유효하고 무효한 lt
함수에 대한 세부정보와 예시는 sort!
를 참조하십시오.
Base.Order.Ordering
— TypeBase.Order.Ordering
어떤 요소 집합에 대한 엄격한 약한 순서를 나타내는 추상 유형입니다. 자세한 내용은 sort!
를 참조하세요.
두 요소를 순서에 따라 비교하려면 Base.Order.lt
를 사용하세요.
Base.Order.lt
— Functionlt(o::Ordering, a, b) -> Bool
주어진 순서 o
에 따라 a
가 b
보다 작은지 테스트합니다.
Base.Order.ord
— Functionord(lt, by, rev::Union{Bool, Nothing}, order::Ordering=Forward)
Ordering
객체를 sort!
에서 사용된 것과 동일한 인수로 구성합니다. 요소는 먼저 by
함수(이는 identity
일 수 있음)에 의해 변환된 다음, lt
함수 또는 기존의 정렬 order
에 따라 비교됩니다. lt
는 isless
또는 sort!
의 lt
매개변수와 동일한 규칙을 준수하는 함수여야 합니다. 마지막으로, 결과 정렬은 rev=true
인 경우 반전됩니다.
isless
가 아닌 lt
와 Base.Order.Forward
또는 Base.Order.Reverse
가 아닌 order
를 함께 사용하는 것은 허용되지 않으며, 그렇지 않으면 모든 옵션은 독립적이며 가능한 모든 조합에서 함께 사용할 수 있습니다.
Base.Order.Forward
— ConstantBase.Order.Forward
기본 정렬은 isless
에 따릅니다.
Base.Order.ReverseOrdering
— TypeReverseOrdering(fwd::Ordering=Forward)
주문을 반전시키는 래퍼입니다.
주어진 Ordering
o
에 대해, 모든 a
, b
에 대해 다음이 성립합니다:
lt(ReverseOrdering(o), a, b) == lt(o, b, a)
Base.Order.Reverse
— ConstantBase.Order.Reverse
isless
에 따라 역순으로 정렬합니다.
Base.Order.By
— TypeBy(by, order::Ordering=Forward)
Ordering
는 by
함수에 의해 변환된 요소에 order
를 적용합니다.
Base.Order.Lt
— TypeLt(lt)
Ordering
는 lt(a, b)
를 호출하여 요소를 비교합니다. lt
는 sort!
의 lt
매개변수와 동일한 규칙을 준수해야 합니다.
Base.Order.Perm
— TypePerm(order::Ordering, data::AbstractVector)
Ordering
는 data
의 인덱스에 대해 i
가 j
보다 작으면 data[i]
가 data[j]
보다 작다는 것을 의미합니다. order
에 따라 data[i]
와 data[j]
가 같을 경우, i
와 j
는 숫자 값으로 비교됩니다.