2014-11-07 3 views
1

스칼라 슬라이스 방법의 시간 복잡도 란 무엇입니까? O(m) 또는 O(n), 입니다. 여기서 m은 slice의 요소 수이고 n은 컬렉션의 요소 수입니다.스칼라에서 슬라이스의 시간 복잡도 란 무엇입니까?

더 구체적인 질문 : 시간 복잡도는 someMap.slice(i, i + 1).keys.head이고, 여기서 i는 someMap.size보다 작은 임의의 정수입니다. 슬라이스 복잡도가 O(m) 인 경우 O(1)이어야합니다. 맞습니까?

+0

구현에 따라 다릅니다. 예를 들어, 목록에서 보통 오래된 조회는'O (n)'이므로'O (m) '에서 슬라이스 할 수 없습니다. –

+0

목록에서 슬라이스가 목록의 시작 부분에 가까울 경우 O (n)보다 빠른 O (until) (실제로 O (max (n, until)))가 있습니다. 목록을 얼마나 오래 보관하든 상관하지 않습니다. 그러나 그것은 O (m)가 아닙니다. 이것은 ~까지입니다. 슬라이스의 시작 부분까지 돈을 지불해야합니다. –

+0

@DidierDupont Big-O 표기법은 항상 최악의 경우 분석입니다. 'O (max (n, until))'이라고 말하면'until <= n' 인 경우'O (n)'을 의미합니다. – Nate

답변

4

이것은 분명히 기본 데이터 형식에 따라 다릅니다. 예를 들어 Array, ArrayBuffer, ByteBuffer 또는 IndexedSeqOptimized의 다른 하위 클래스를 자르는 것은 k 요소를 컨테이너에서 자르는 경우 O(k)입니다. 예를 들어, List은 으로 볼 수있는 O(n)입니다. 특정 유형의 출처를 확인하고 싶을 것입니다.

MapIterableLike에서 슬라이스 구현을 가져옵니다. 아래에 붙여 넣은 구현에서 컬렉션의 요소를 반복하는 비용과 새로 빌드 한지도를 만드는 데 드는 비용을 분명히 알 수 있습니다.

TreeMap의 경우 k 개 요소를지도에서 자르는 경우 O(n + k lg k)이어야합니다.

HashMap의 경우이 값은 O(n)이어야합니다.

override /*TraversableLike*/ def slice(from: Int, until: Int): Repr = { 
    val lo = math.max(from, 0) 
    val elems = until - lo 
    val b = newBuilder 
    if (elems <= 0) b.result() 
    else { 
    b.sizeHintBounded(elems, this) 
    var i = 0 
    val it = iterator drop lo 
    while (i < elems && it.hasNext) { 
     b += it.next 
     i += 1 
    } 
    b.result() 
    } 
} 

의심스러운 경우 소스를 확인하십시오.

+0

감사합니다. 나는 그것이 어떻게 구현되는지에 대해 확신이 서지 않았다. 또한, slice는 O (n)의 복잡성으로 인해 O (n)입니다. – ov7a

+1

@ChelovekChelovechnii 슬라이스는 일반적으로 'O (n)'이 아닙니다. 'IterableLike.slice (...) '를 바꾸려면 요소를 반복하는 비용 +'k'요소의 새 컨테이너를 만드는 데 드는 비용입니다. iterating 부분은'drop'과 while 루프로 구성됩니다. 그것은'O (n)'로 묶인'O (from) + O (k)'입니다. 'IndexedSeqOptimized'의'drop'은'O (1)'입니다. – Nate

+0

나는 그것을 얻지 않는다! Array의 slice 소스 코드에는 while 루프가 있습니다. 어떻게 O (1)이 될 수 있습니까? 'var에 나는 = 보라 동안 (내가 안녕하세요 <) { B + = 자기 (I) 내가 + = 1 } b.result()' –