2010-10-21 27 views
6

Estoy tratando de hacer una función recursiva para obtener la transposición de una lista de listas, n x p a p x n. Pero no puedo hacerlo. He sido capaz de hacer una función para transponer una lista de listas 3 x n a un n x 3 uno:transposición de una lista de listas

let rec drop1 list= 
    [(match (List.nth list 0) with [] -> [] | a::b -> b); 
    (match (List.nth list 1) with [] -> [] | a::b -> b); 
    (match (List.nth list 2) with [] -> [] | a::b -> b);] 

let rec transpose list= 
    if List.length (List.nth list 0) == 0 then [] 
    else [(match (List.nth list 0) with [] -> 0 | a::b -> a); 
      (match (List.nth list 1) with [] -> 0 | a::b -> a); 
      (match (List.nth list 2) with [] -> 0 | a::b -> a)] 
     :: transpose (drop1 list) 

Pero no soy capaz de generalizar. Estoy pensando en la dirección equivocada. ¿Es esto generalizable? ¿Hay una mejor solución? Por favor ayuda.

Respuesta

10
let rec transpose list = match list with 
| []    -> [] 
| [] :: xss -> transpose xss 
| (x::xs) :: xss -> 
    (x :: List.map List.hd xss) :: transpose (xs :: List.map List.tl xss) 
+1

+1, ¡Guau! No estaba al tanto de la función List.map. El manual dice que no es recursivo en la cola. ¿Qué efecto puede tener eso si uso esto en un código más grande? – lalli

+1

@lalli: para listas muy grandes puede causar un desbordamiento de la pila. En ese caso, debe usar 'List.rev_map' en su lugar y luego recorrer las listas al final e invertirlas. Sin embargo, tenga en cuenta que mi definición de 'transposición 'tampoco es recursiva de cola (tampoco es la suya). – sepp2k

+4

No debe preocuparse por la recursividad de la cola al principio; intenta tener una implementación simple y clara. Usar una función de "transposición" en ('una lista de listas) con listas muy grandes es probablemente una muy mala idea de todos modos. Si tiene muchos datos, probablemente sea más apropiada otra estructura de datos (por ej., Una matriz indexada por (int * int), que tenga una función 'transpose' de tiempo constante). – gasche