Ho scritto un generatore di permutazioni per liste Scala che genera tutte le permutazioni di una data lista. Finora, ho il seguente basato su this Haskell implementation (e penso che sia più efficiente di molte altre opzioni che ho provato). Ci sono dei modi per renderlo ancora più efficiente, o ho coperto tutte le mie basi?Generatore di permutazione più veloce
/** For each element x in List xss, returns (x, xss - x) */
def selections[A](xss:List[A]):List[(A,List[A])] = xss match {
case Nil => Nil
case x :: xs =>
(x, xs) :: (for((y, ys) <- selections (xs))
yield (y, x :: ys))
}
/** Returns a list containing all permutations of the input list */
def permute[A](xs:List[A]):List[List[A]] = xs match {
case Nil => List(Nil)
//special case lists of length 1 and 2 for better performance
case t :: Nil => List(xs)
case t :: u :: Nil => List(xs,List(u,t))
case _ =>
for ((y,ys) <- selections(xs); ps <- permute(ys))
yield y :: ps
}
È più veloce del metodo di scambio basato su array? O intendi "generatore di permutazione funzionale più veloce"? (Non lo hai mai detto esplicitamente, ma hai aggiunto il tag ....) –
Intendo il generatore di permutazione funzionale più veloce. Per questo motivo, non ho provato a confrontarlo con il metodo di swap basato su array. –
Ci sono algoritmi migliori. Ne ho visto uno qui su Stack Overflow non molto tempo fa, in Scala, che ha restituito la permutazione successiva (assumendo un insieme di indici), invece di una lista di tutte le permutazioni. Ha usato 'partition' per trovare il punto della successiva permutazione dell'indice e, in generale, ha evitato le chiamate ricorsive non-tail. Inoltre, ovviamente, l'implementazione di Haskell del codice che hai mostrato sarebbe stata molto veloce, perché non avrebbe calcolato nulla in anticipo. :-) –