Ho fatto alcune analisi degli algoritmi di ordinamento in F # qualche anno fa in uno stile molto imperativo; Stavo cercando di battere l'implementazione di magazzino .NET e sono riuscito a farlo here. Sono andato a dare la seguente risposta a me stesso oggi, ma FPish non mi permetterà di creare un account. Argh! Devo rendere il mio post da qualche parte, e qui è buono come ovunque, lol ...
Durante la lettura di "Learn You a Haskell per Great Good" ieri, l'autore ha creato un esempio per implementare quicksort. La descrizione era abbastanza chiara e ancor prima di arrivare al codice di esempio, una elegante soluzione ricorsiva (in Haskell) mi è venuta in mente. Immagino che non abbia mai avuto una sensazione intuitiva per come quicksort fa la sua cosa, perché la soluzione banale è abbastanza facile, se non molto efficiente.
Ecco la mia versione in F #:
let rec quicksort = function
| [] -> []
| pivot :: xs ->
(left pivot xs) @ pivot :: (right pivot xs)
and left pivot xs = quicksort [ for x in xs do if x <= pivot then yield x ]
and right pivot xs = quicksort [ for x in xs do if x > pivot then yield x ]
E, l'equivalente Haskell (mi piace questo ... pulita!):
quicksort :: Ord a => [a] -> [a]
quicksort [] = []
quicksort (pivot : xs) =
left ++ pivot : right
where
left = quicksort [ x | x <- xs, x <= pivot ]
right = quicksort [ x | x <- xs, x > pivot ]
Per sorrisi, ecco un altro F # versione (per lo più tail-ricorsiva) che è circa 2 volte la velocità della versione banale. Non hanno preso la briga di tempo questo contro il mio post originale, però, quindi nessuna idea come impila fino alla versione mutabili nel mio OP sul FPish.net (FSHub) da qualche anno fa ...
let rec quicksort' xs =
let rec aux pivot left right = function
| [] -> (quicksort' left) @ pivot :: (quicksort' right)
| x :: xs ->
if x <= pivot then
aux pivot (x :: left) right xs
else
aux pivot left (x::right) xs
match xs with
| [] -> []
| x :: xs -> aux x [] [] xs
fonte
2013-11-15 17:08:29
FWIW , questo è * non * quicksort. In particolare, l'ultima volta che ho messo a confronto Haskell era più lento di 6.000 volte di un vero quicksort scritto in F #. Per informazioni sul vero algoritmo di quicksort (e non sulla versione bastardizzata delle comunità Haskell che manca completamente il punto di essere veloce!), Leggi l'articolo originale di Hoare del 1961: http://comjnl.oxfordjournals.org/cgi/content/short/5/1/10 –