Comment définir une fonction de rotation qui génère toutes les rotations de la liste donnée?
Par exemple: Tourner J'ai écrit une fonction de décalage pouvant réorganiser la commande p> mais je ne comprends pas comment générer ces nouveaux tableaux et les ajouter ensemble. p> p> [1,2,3,4] = [[1,2,3,4], [ 2,3,4,1], [3,4,1,2], [4,1,2,3]] code> p>
8 Réponses :
Je pense que ce sera quelque chose comme ça (je n'ai pas de GHC en ce moment, je ne pouvais donc pas l'essayer)
Il est plus facile et plus lisible pour simplement utiliser itérer code> au lieu d'une fonction d'assistance.
Le suivant
shift :: [a] -> [a] shift [] = [] shift (x:xs) = xs ++ [x] allRotations :: [a] -> [[a]] allRotations l = take (length l) (iterate shift l)
shift (x:xs) = xs ++ [x]
rotates xs = take (length xs) $ iterate shift xs
iterate f x returns the stream ("infinite list") [x, f x, f (f x), ...]. There are n rotations of an n-element list, so we take the first n of them.
Les réponses données jusqu'à présent fonctionnent bien pour les listes finies, mais étant éventuellement une erreur lorsqu'il est donné une liste infinie. (Ils appellent tous ma solution utilise donc lorsque (Dans votre application particulière, il peut ne pas avoir de sens à essayer Pour faire pivoter une liste infinie. D'autre part, cela pourrait. Je soumets cette réponse à la finalité seulement.) p> p> longueur code> sur la liste.) zipwith const code>. ZipWith Const Foos Barres Code> peut apparaître à première vue à être identique à FOOS code> (rappelez que const x y = x code>). Mais la liste renvoyée de zipwith code> se termine lorsque l'une des listes d'entrée se termine. P> xs code> est fini, la liste renvoyée est la même longueur que possible. xs code>, comme nous le souhaitons; et quand xs code> est infini, la liste renvoyée ne sera pas tronquée, alors sera infinie, à nouveau comme nous le voulons. p>
Il n'a pas de sens de soutenir la rotation sur un flux infini du tout i>, iMho; Ce n'est tout simplement pas une opération valide. Entrée infinie, votre fonction simule queues code> ( itération de la queue code>).
Un autre moyen de calculer toutes les rotations d'une liste consiste à utiliser les fonctions prédéfinies queues code> et init code>. La fonction queues code> donne une liste de tous les segments finaux d'une liste tandis que init code> donne une liste de tous les segments initiaux. Par exemple, allRotations [1..]
"Tails" n'est plus pris en charge dans la version récente de Haskell. inite 'Peut-être que vous vouliez dire code> init' (importé de prélude)
Il faut d'abord "importer des données.list"
Je préférerais les solutions suivantes, à l'aide des fonctions intégrées pour votre exemple cycle code> et queues code>: [1,2,3,4] code> la fonction cycle code> produit une liste infinie [1,2,3,4,1,2,3,4,1, 2 ...] code>. La fonction queues code> génère toutes les queues possibles à partir d'une liste donnée, ici [[[1,2,3,4,1,2 ...], [2,3,4,1, 2,3 ...], [3,4,1,2,3,4 ...], ...] code>. Maintenant, tout ce que nous avons à faire est de réduire les "queues" - les "queues" à la longueur 4 et couper la liste globale à la longueur 4, ce qui est fait en utilisant prendre code>. L'alias len code> a été introduit pour éviter de recalculer longueur xs code> plusieurs fois. P> p>
myRotate lst = lst : myRotateiter lst lst
where myRotateiter (x:xs) orig
|temp == orig = []
|otherwise = temp : myRotateiter temp orig
where temp = xs ++ [x]
Je suggère: