문제

을 얻고 싶은 가장 큰 100 요소의 목록에서 이상 100000000 숫자입니다.

수종 전체 목록을 마지막 100 의 요소를 정렬된 목록은,그러나 매우 비싼 것 모두의 측면에서 메모리와 시간입니다.

은 거기에 기존의 모든기 쉬운,pythonic 의 방법으로 이것을 하고 있는가?

내가 원하는 것은 다음과 같은 기능을 대신 순수입니다.실제로 나는 원하지 않는 시간을 낭비하는 요소를 정렬 나는 걱정하지 않는다.

예를 들어,이 기능이 내가 가지고 싶다면:

getSortedElements(100, lambda x,y:cmp(x,y))

참고:이 요건은 성과를 위한 관점입니다.

도움이 되었습니까?

해결책

표준 라이브러리의 heapq 모듈은 다음을 수행 할 nlargest () 함수를 제공합니다.

top100 = heapq.nlargest(100, iterable [,key])

전체 목록을 정렬하지 않으므로 필요하지 않은 요소에 시간을 낭비하지 않습니다.

다른 팁

선택 알고리즘 여기서 도와야합니다.

매우 쉬운 해결책은 100 번째로 큰 요소를 찾은 다음이 요소보다 큰 요소를 선택하는 목록을 통해 실행하는 것입니다. 그것은 당신에게 100 개의 가장 큰 요소를 줄 것입니다. 이것은 목록의 길이에서 선형입니다. 이것은 최선입니다.

더 정교한 알고리즘이 있습니다. ㅏ 더미, 예를 들어,이 문제에 매우 적합합니다. 힙 기반 알고리즘은입니다 n log k 어디 n 목록의 길이입니다 k 선택하려는 가장 큰 요소의 수입니다.

이것에 대한 토론이 있습니다 문제 선택 알고리즘의 Wikipedia 페이지에서.

편집 : 다른 포스터는 Python 이이 문제에 대한 솔루션을 내장되어 있다고 지적했습니다. 분명히 그것은 자신의 것을 굴리는 것보다 훨씬 쉽지만, 그러한 알고리즘이 어떻게 작동하는지 알고 싶을 때이 게시물을 유지하겠습니다.

당신이 사용할 수 있는 힙 데이터 구조입니다.힙지는 않을 것입니다 주문했지만,그것은 상당히 빠른 방법으로 유지하는 반기문한 데이터,그리고 그것의 가장 작은 항목은 항상 첫번째 요소에 힙.

힙은 두 개의 기본 작업에 도움이 될 것입니다:추가 및 대체합니다.

기본적으로 당신이 할 것은에 항목을 추가 그것을 얻을 때까지 100 항목(최 N 번호는 당신의 질문에).그 후,당신은 대체는 첫 번째 항목과 함께 모든 새로운 항목으로 새로운 항목을 보다 더 큰 첫 번째 항목입니다.

을 교체할 때마다 먼저 항목과 함께 무언가 크고,내부 코드에 힙 조정할 것입니다 힙 내용하는 경우 있도록 새로운 항목되지 않은 가장 작은,그것이 거대한 힙으로,그리고 최소 항목이"거품을"처음 요소 할 준비가 대체합니다.

이를 수행하는 가장 좋은 방법은 100 개의 항목이 있으면 팝업 된 우선 순위 대기열을 유지하는 것입니다.

결과가 정렬되었는지 상관하지 않지만 직관적으로 분명합니다. 상위 100 개가 있다는 것을 알기 위해서는 효율적인 데이터 구조를 통해 현재 상단 번호 목록을 순서대로 주문해야합니다. 그 구조는 각 요소의 최소값, 최대 및 상대적 위치를 자연스럽게 이웃 옆에 위치한다고 주장 할 수있는 자연스러운 방식으로 알 수 있습니다.

파이썬에서 언급 된 바와 같이 heapq를 사용합니다. Java Priorityque에서 :http://java.sun.com/javase/6/docs/api/java/util/priorityqueue.html

다음은 라이브러리와 무관하며 배열이있는 모든 프로그래밍 언어로 작동하는 솔루션입니다.

초기화 :

Make an array of 100 elements and initialise all elements
with a low value (less than any value in your input list).

Initialise an integer variable to 0 (or any value in
[0;99]), say index_minvalue, that will point to the
current lowest value in the array.

Initialise a variable, say minvalue, to hold the current 
lowest value in the array.

각 값에 대해 입력 목록에서 current_value를 말하십시오.

if current_value > minvalue

  Replace value in array pointed to by index_minvalue
  with current_value

  Find new lowest value in the array and set index_minvalue to
  its array index. (linear search for this will be OK as the array
  is quickly filled up with large values)

  Set minvalue to current_value

else
  <don't do anything!>

MinValue는 빠르게 높은 값을 얻을 수 있으므로 입력 목록의 대부분의 값은 MinValue 와만 비교하면됩니다 (비교 결과는 대부분 False).

청중의 알고리즘의 경우 : Tony Hoare의 알고리즘에 간단한 변형 으로이 작업을 수행 할 수 있습니다. 찾다:

find(topn, a, i, j)
   pick a random element x from a[i..j]
   partition the subarray a[i..j] (just as in Quicksort) 
     into subarrays of elements <x, ==x, >x
   let k be the position of element x
   if k == 0 you're finished
   if k > topn, call find(topn, a, i, k)
   if k < topn, call find(topn-k, k, j)

이 알고리즘은 가장 큰 것입니다 topn 첫 번째 요소 topn 배열의 요소 a, 없이 정렬. 물론, 정렬을 원하거나 단순화를 원한다면 힙이 더 좋으며 라이브러리 기능을 호출하는 것이 더 좋습니다. 그러나 멋진 알고리즘입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top