转置列表清单

lal*_*lli 7 ocaml

我试图做一个递归函数来获取一个列表的列表的转置n x pp x n.但我无法这样做.我已经能够创建一个函数来将3 x n列表列表转换为一个列表n x 3:

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)
Run Code Online (Sandbox Code Playgroud)

但我无法概括它.我肯定在想错误的方向.这可以推广吗?有更好的解决方案吗?请帮忙.

sep*_*p2k 11

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)
Run Code Online (Sandbox Code Playgroud)

  • 你最初不应该担心尾递归; 尝试简单明了的实现.无论如何,在('列表列表)上使用具有非常大的列表的"转置"功能可能是一个非常糟糕的主意.如果你有很多数据,那么另一个数据结构(例如,由(int*int)索引的矩阵,其具有恒定时间`transpose`函数)可能更合适. (4认同)

naa*_*jie 5

我知道这是一个老问题,但我最近必须解决这个问题,作为我正在进行的练习的一部分,我遇到了 @sepp2k 的解决方案,但我无法理解它是如何工作的,所以我尝试通过我。

这本质上是相同的算法,但更简洁一些,因为它不会破坏列表的列表。我想我会将其发布在这里,以防其他人正在搜索,并且可能会发现这种表达方式很有用:

let rec transpose = function
   | [] 
   | [] :: _ -> []
   | rows    -> 
       List.map List.hd rows :: transpose (List.map List.tl rows)
Run Code Online (Sandbox Code Playgroud)