Partage
  • Partager sur Facebook
  • Partager sur Twitter

[OCaml] Convertir un list list en array array

Sujet résolu
    12 décembre 2010 à 17:34:47

    Bonsoir,

    J'essaye en vain de convertir une list list en matrice mais je n'arrive pas, j'ai envie de convertir ce genre de liste :
    [[];[0;0;1];[1;0;0;1];[0 ;1 ;0] ;[1];[];[] ]

    en :
    [|[|2; 2; 2; 2; 2; 2; 2|]; 
      [|2; 2; 2; 2; 2; 2; 2|];
      [|2; 2; 1; 2; 2; 2; 2|]; 
      [|2; 0; 0; 0; 2; 2; 2|]; 
      [|2; 0; 0; 1; 2; 2; 2|]; 
      [|2; 1; 1; 0; 1; 2; 2|]
     |]


    Voici ce que j'ai essayé mais cela ne fonctionne pas, j'ai un index_of_bounds exception. Je ne sais pas où je dépasse les index limites :

    (* fonction qui permet de convertir une liste en matrix *)
    let convertListToMatrix 
    (listeAconvertir : 'a list list)
    : 'a array array 
    =
    let matrixVide = let init = Array.make 7 2 in 
    		 let vect = Array.init 6 (fun _ -> Array.copy init) in 
    		     vect 
    		 in let rec remplirMatrix listes i j = 
    		    match listes with
    			[[]; []; []; []; []; []; []] -> [|[|2; 2; 2; 2; 2; 2; 2|]; [|2; 2; 2; 2; 2; 2; 2|];
        							  [|2; 2; 2; 2; 2; 2; 2|]; [|2; 2; 2; 2; 2; 2; 2|];
        							  [|2; 2; 2; 2; 2; 2; 2|]; [|2; 2; 2; 2; 2; 2; 2|]
    							 |]
    		       | [] 		      -> for i = 5 downto 0 do
    						     matrixVide.(i).(j) <- 2
    						 done;	
    						 matrixVide
      		       | premiereListe::queue -> let rec copieListeToColonneMatrix listAcopier i j = 
    							 match listAcopier with
    							  []           -> if premiereListe = [] then
    									     for k = 5 downto 0 do
    								             matrixVide.(k).(j) <- 2
    								             done
    									  else
    									     matrixVide.(i).(j) <- 2
    							 | tete::queues -> if i >= 0 && j < 7 then 
    									  begin
    									   matrixVide.(i).(j) <- tete;
    									   copieListeToColonneMatrix queues (i - 1) (j)
    									  end
    									  else copieListeToColonneMatrix [] i j
    
    					   	 in begin 
    					         	copieListeToColonneMatrix premiereListe 5 0;
    						 	remplirMatrix (queue) (i)(j+1) 
    						 end
    		    in remplirMatrix (listeAconvertir) 5 0;			
    matrixVide
    ;;
    


    Si y a une autre méthode de parcours, merci de me le dire svp.
    Cordialement.
    Edit :
    La soluce pour ceux qui ont auront besoin :)


    (* fonction qui permet de convertir une liste en matrix *)
    let convertListToMatrix 
    (listeAconvertir : 'a list list)
    : 'a array array 
    =
    let matrixVide = let init = Array.make 7 2 in 
    		 let vect = Array.init 6 (fun _ -> Array.copy init) in 
    		     vect 
    		 in let rec remplirMatrix listes i j = 
    		    match listes with
    		       | [] 		      -> 
    						 matrixVide
      		       | premiereListe::queue -> let rec copieListeToColonneMatrix listAcopier i j = 
    							 match listAcopier with
    							  []           -> if premiereListe = [] then
    									     for k = 5 downto 0 do
    								             matrixVide.(k).(j) <- 2
    								             done
    									  else
    									     matrixVide.(i).(j) <- 2
    							 | tete::queues -> if i >= 0 && j < 7 then 
    									   begin
    									    matrixVide.(i).(j) <- tete;
    									    copieListeToColonneMatrix queues (i - 1) (j)
    									   end
    									   else copieListeToColonneMatrix [] i j
    					   	 in begin 
    					         	copieListeToColonneMatrix premiereListe i j;
    						     if j < 7 then
    						 	remplirMatrix (queue) (i)(j+1) 
    						     else matrixVide
    						 end
    		    in remplirMatrix (listeAconvertir) 5 0;			
    matrixVide
    ;;
    
    • Partager sur Facebook
    • Partager sur Twitter
      12 décembre 2010 à 18:47:29

      Un poil plus simple ^^ :
      let convert ll = Array.of_list (List.map Array.of_list ll);;
      

      EDIT : ha non, ce n'est pas ce que tu veux, j'ai été trop vite, désolé. Je ne comprend pas trop ton opération de conversion : c'est surement très spécifique à ton projet.

      • Partager sur Facebook
      • Partager sur Twitter
        12 décembre 2010 à 19:01:55

        Bonjour,

        Alors j'ai regardé un peu ça, et j'ai trouvé un truc qui fonctionne, disons que ça m'a servi d'exercice :lol:

        Plusieurs notes, je ne fais pas d'OCaml mais du F# donc certaines instructions seront sans doute à adapter mais comme F# est basé sur OCaml dans l'ensemble ça devrait aller.
        Après comme je suis encore débutant en programmation fonctionnelle c'est peut-être pas tip-top...

        let listToMatrix lli =
          let result = Array.init 6 (fun _ -> Array.create 7 2)
        
          let rec outer = function
            | h :: tl, col ->
              let rec inner = function
                | h :: tl, row ->
                  result.[row].[col] <- h
                  inner (tl, row + 1)
                | _ -> ()
        
              inner (h, 6 - List.length h)
              outer (tl, col + 1)
            | _ -> ()
        
          outer (lli, 0)
          result
        


        Pour l'explication:
        Je commence par créer un tableau remplis de 2
        je boucle récursivement sur un tuple contenant la liste de liste ainsi que la colonne du tableau
        tant qu'elle n' est pas vide je rentre dans la boucle interne en lui passant la liste intérieure actuelle et le premier index de ligne où il n'y aura pas un 2 (nbre lignes - taille liste)
        tant qu'elle n'est pas vide je met à jour la valeur du tableau avec la tête de liste et je ré-itères avec la queue et la ligne suivante
        quand j'ai fini avec cette sous-liste (second cas du match) on ne fait rien, et on remonte donc dans la fonction externe (outer) je passe à la sous-liste suivante en incrémentant la colonne du tableau

        quand on a fini tout ça je renvoi simplement le tableau.

        Notons que je profite de l'aspect mutable du tableau, je sais pas si c'est la meilleure approche...

        Cordialement !

        PS désolé pour l'explication textuelle un peu foireuse c'est pas ma tasse de thé lol

        Edit: j'aurais pu généraliser pour éviter les valeurs numériques en dur (et peut-être aussi faire un peu plus de vérifications... quid de ce qu'il se passe si la sous-liste contient plus d'éléments que le nombre de lignes du tableau ? ^^)

        • Partager sur Facebook
        • Partager sur Twitter
        Censément, quelqu'un de sensé est censé s'exprimer sensément.
          12 décembre 2010 à 20:55:43

          Je vous remercie pour vos suggestions :)
          • Partager sur Facebook
          • Partager sur Twitter

          [OCaml] Convertir un list list en array array

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown