11
votes

Comment définir une fonction de rotation

Comment définir une fonction de rotation qui génère toutes les rotations de la liste donnée?

Par exemple: Tourner [1,2,3,4] = [[1,2,3,4], [ 2,3,4,1], [3,4,1,2], [4,1,2,3]]

J'ai écrit une fonction de décalage pouvant réorganiser la commande xxx

mais je ne comprends pas comment générer ces nouveaux tableaux et les ajouter ensemble.


0 commentaires

8 Réponses :


0
votes

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) xxx


1 commentaires

Il est plus facile et plus lisible pour simplement utiliser itérer au lieu d'une fonction d'assistance.



4
votes

Le suivant

shift :: [a] -> [a]
shift [] = []
shift (x:xs) = xs ++ [x]

allRotations :: [a] -> [[a]]
allRotations l = take (length l) (iterate shift l)


0 commentaires

5
votes
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.

0 commentaires

1
votes

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 longueur sur la liste.) xxx

ma solution utilise zipwith const . ZipWith Const Foos Barres peut apparaître à première vue à être identique à FOOS (rappelez que const x y = x ). Mais la liste renvoyée de zipwith se termine lorsque l'une des listes d'entrée se termine.

donc lorsque xs est fini, la liste renvoyée est la même longueur que possible. xs , comme nous le souhaitons; et quand xs est infini, la liste renvoyée ne sera pas tronquée, alors sera infinie, à nouveau comme nous le voulons.

(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.)


1 commentaires

Il n'a pas de sens de soutenir la rotation sur un flux infini du tout , iMho; Ce n'est tout simplement pas une opération valide. Entrée infinie, votre fonction simule queues ( itération de la queue ).



23
votes

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..]


2 commentaires

"Tails" n'est plus pris en charge dans la version récente de Haskell. : 30: 1: pas dans la portée: inite 'Peut-être que vous vouliez dire init' (importé de prélude)


Il faut d'abord "importer des données.list"



1
votes

Je préférerais les solutions suivantes, à l'aide des fonctions intégrées cycle et queues : xxx

pour votre exemple [1,2,3,4] la fonction cycle produit une liste infinie [1,2,3,4,1,2,3,4,1, 2 ...] . La fonction queues 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 ...], ...] . 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 . L'alias len a été introduit pour éviter de recalculer longueur xs plusieurs fois.


0 commentaires

0
votes
myRotate lst = lst : myRotateiter lst lst
  where myRotateiter (x:xs) orig
          |temp == orig = []
          |otherwise = temp : myRotateiter temp  orig               
          where temp = xs ++ [x]

0 commentaires

0
votes

Je suggère: xxx


0 commentaires