如何仅使用OCaml列表模块形成列表矩阵列表?

时间:2016-04-19 00:51:31

标签: list matrix ocaml transpose higher-order-functions

我想知道如何使用O'Caml

形成矩阵

我从元组列表中形成了一个普通列表,通过以下方式指示索引和元素:

  List.map (fun (idx, x) -> x ) list

我想在不使用递归或循环的情况下为矩阵执行此操作。只是高阶函数和List.module

(上下文:我试图转置给定矩阵的矩阵)

1 个答案:

答案 0 :(得分:2)

我认为你的方法可行,但它可能不是最快的方法。

从一组索引和元素构造列表(或列表列表)没有简单的功能。由于索引可能具有的所有值(重复,缺失值,乱序等),很难对这样的函数进行简洁明确的定义。

我会说缺少的步骤是将三元组列表排序为所需的顺序。由于List模块中有一个sort函数,因此可能是您的限制所允许的。

本质上,原始订单按第一个索引排序,然后按第二个索引排序。因此,要获得转置,您希望按第二个索引排序,然后是第一个索引。

在您获得正确的订单后,您可以使用List.fold_left或List.fold_right来汇总最终的清单列表。

这是一个使用List.fold_left将列表重新格式化为三个组的函数。这不是你想要的功能,但它可能很接近:

let bythrees l =
    let iby (cur, prev, n) x =
        if n mod 3 = 2 then ([], (x :: cur) :: prev, n + 1)
        else (x :: cur, prev, n + 1)
    in
    let (_, res, _) = List.fold_left iby ([], [], 0) l in
    res

以下是运行时的外观:

# bythrees [1;2;3;4;5;6;7;8;9];;
- : int list list = [[9; 8; 7]; [6; 5; 4]; [3; 2; 1]]

输出仍然需要一些工作,但这表明你可以用这种方式列出一个列表。