algorithm - 翻转二维列表(或列表列表)的维度,其中每个子列表具有相等的长度

标签 algorithm list recursion f#

我有一个列表列表,其中每个内部列表的长度都相同,我需要将其投影为它的倒数(也就是说,我需要翻转维度)。

换句话说,获取每个子列表的第一项并将其放入新列表,获取每个子列表的第二项并将其放入新列表等。然后返回所有这些新列表的列表。

例子:如果输入是:

let ls = [[1;2;3];[4;5;6];[7;8;9];[0;0;0]];;

那么输出应该是:

val it : int list list = [[1; 4; 7; 0]; [2; 5; 8; 0]; [3; 6; 9; 0]]

我有工作代码,但感觉不对。它遍历列表多次,需要多次执行 List.rev 并且必须检查内部列表是否为空:

let rec getInnerHeads acc skipped lst =
    match lst with
    | [] -> List.rev acc, List.rev skipped
    | item::rest ->
        match item with
        | [] -> [], skipped
        | innerHead::skip1 ->
            getInnerHeads (innerHead::acc) (skip1::skipped) rest

let rec flipDimensions acc lst =
    match lst with
    | [] -> acc |> List.rev
    | z when (z |> List.forall List.isEmpty) -> acc |> List.rev
    | rest ->
        let (elem, skip1Elems) = getInnerHeads [] [] rest
        flipDimensions (elem::acc) skip1Elems

上述代码的唯一优点是它是轨道递归的(至少我认为是)。

有人有更高效、更简洁或两者兼而有之的算法吗?我检查了 F# Snippets 和 SO,认为以前有人问过这个问题,它看起来很常见,但我没有找到任何示例。

也许是 List.unfold 的东西?

最佳答案

let transpose matrix =
    let rec loop acc = function
        | (_::_)::_ as m -> loop (List.map List.head m :: acc) (List.map List.tail m)
        | _ -> List.rev acc
    loop [] matrix

关于algorithm - 翻转二维列表(或列表列表)的维度,其中每个子列表具有相等的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53897277/

相关文章:

algorithm - 排列游戏 - 第二个输入案例 - 解释

java - 我怎样才能加快我的多数元素问题集的以下算法?

java - 在列表中查找回文

html - IE9 CSS 在 li 中排列两个元素的问题

c++ - 具有无限子节点的树的递归函数。 C++

algorithm - 如何使用 CUDA 从 M 个元素中获取 N 个最大元素,其中 N << M?

java - 我正在尝试实现一个 Queue 来反转堆栈并打印堆栈 FIFO?

python - 实现字典函数来计算列表的平均值

javascript - Node.js 用递归函数以某种方式改变了我的对象

recursion - "continuations"在函数式编程中是什么意思?(特别是 SML)