Partage

[OCaml] Convertir un list list en array array

Sujet résolu
Le 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
;;
Publicité
Le 12 décembre 2010 à 17:34:47
Le 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.

Le 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 ? ^^)

Le 12 décembre 2010 à 20:55:43

Je vous remercie pour vos suggestions :)

[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é.
  • Editeur
  • Markdown