quello che vuoi è un buon selection algorithm
Il seguente codice Python si basa intorno alla funzione di partizione partition()
divide la lista in due. I valori inferiori a "pivotValue" vengono spostati all'inizio dell'elenco. I valori maggiori di pivotValue vengono spostati alla fine dell'elenco. Questo avviene nelle operazioni O (N) passando dall'elenco dall'inizio alla fine, ogni volta che guarda un valore lo sposta vicino all'inizio della lista, solo se è più piccolo del valore pivot.
(nel tuo caso, in realtà, spostiamo i valori più grandi all'inizio della lista poiché vuoi che i valori più grandi non siano i più piccoli).
Una volta partizionato l'elenco in tempo O (N), restiamo con m numeri grandi all'inizio della lista. se m = 10 allora ottimo, ecco i tuoi dieci più grandi numeri. se m è più grande di 10, allora dobbiamo dividere nuovamente i numeri più grandi per ottenere i 10 numeri più grandi dai più grandi numeri. se m è minore di 10 allora abbiamo bisogno di 10 m più numeri, quindi partizioniamo la parte più rara per trovare i numeri da 10 m e li aggiungiamo ai nostri numeri m per ottenere i 10 numeri necessari.
Così continuiamo a partizionare finché non abbiamo 10 numeri più grandi. Questo è fatto dal metodo select()
. L'intero metodo è di solito molto veloce perché ogni volta che facciamo una partizione ci rimane circa la metà dei numeri da gestire. (se dividi costantemente il numero di numeri che devi considerare per due, va bene). Ogni volta che facciamo una partizione che produce più di 10 numeri più grandi, possiamo ignorare un intero mucchio di numeri troppo piccoli.
Ecco il codice:
def partition(_list,left,right,pivotIndex):
pivotValue=_list[pivotIndex]
_list[right],_list[pivotIndex]=pivotValue,_list[right]
storeIndex=left
for i in range(left,right):
if _list[i] > pivotValue:
_list[storeIndex],_list[i]=_list[i],_list[storeIndex]
storeIndex+=1
_list[right],_list[storeIndex]=_list[storeIndex],_list[right]
return storeIndex
from random import randint
def select(_list,left,right,k):
if left==right:
return _list[:left+1]
pivotIndex=randint(left,right)
pivotNewIndex=partition(_list,left,right,pivotIndex)
pivotDist=pivotNewIndex-left+1
if pivotDist==k:
return _list[:pivotNewIndex+1]
elif k<pivotDist:
return select(_list,left,pivotNewIndex-1,k)
else:
return select(_list,pivotNewIndex+1,right,k-pivotDist)
_list=[1,2,109,2234,23,6,1,234,11,4,12451,1]
left=0
right=len(_list)-1
pivotIndex=4
print _list
"[1, 2, 109, 2234, 23, 6, 1, 234, 11, 4, 12451, 1]"
print partition(_list,left,right,pivotIndex) #partition is order(N).
"7" #index 7, so the lowest number are in the first 7 numbers of the list [1, 2, 1, 6, 1, 11, 4, 23]
print _list
"[1, 2, 1, 6, 1, 11, 4, 23, 2234, 109, 12451, 234]"
print select(_list,left,right,10)
"[1, 2, 1, 1, 4, 11, 6, 23, 109, 234]"
with open('nums.txt') as f:
numbers=map(int,f.readlines())
print select(numbers,0,len(numbers)-1,10)
"[1132513251, 2000, 23512, 13252365, 1235, 1251, 324, 100, 82, 82]"
È questo compito? O un esercizio da un libro? – ChrisW
È compito di casa .. –
Questo è ovviamente un [problema XY] (http://www.perlmonks.org/?node_id=542341). Il problema non è l'ordinamento, ma la ricerca dei dieci maggiori numeri interi. Mentre possono essere trovati prima ordinando e quindi selezionando le prime dieci voci, questa non è la soluzione migliore. La soluzione migliore è quella fornita da _pepsi_. – pillmuncher