【问题标题】:Combining a column of lists in OCaml在 OCaml 中组合一列列表
【发布时间】:2016-04-18 13:13:28
【问题描述】:

我想在 OCaml 中转置一个矩阵(不使用递归或任何类型的循环)

例如,如果我有以下矩阵:[[1;2];[3;4]],
我想要[[1;3];[2;4]]的输出。

到目前为止,我所做的是将原始矩阵分解为单独的列:

//function that separates into cols
let separate li =
    List.map (fun x -> [x]) li;;

我从另一个函数调用这个辅助函数:

let trans x = 
    List.concat (List.map separate li) x;;

我在想这会以我想要的方式组合所有列,而是以以下输出结束:[[1];[2];[3];[4]]

【问题讨论】:

    标签: ocaml


    【解决方案1】:

    我质疑您的 separate 函数是否将矩阵分成列。这是我看到的:

    # let separate li = List.map (fun x -> [x]) li;;
    val separate : 'a list -> 'a list list = <fun>
    # List.map separate [[1;2];[3;4]];;
    - : int list list list = [[[1]; [2]]; [[3]; [4]]]
    

    我没有看到列,我只是看到您已将每个矩阵元素放入其自己的列表中。

    要获得第一列,您可以试试这个:

    # List.map List.hd [[1;2]; [3;4]];;
    - : int list = [1; 3]
    

    如果你使用List.tl 而不是List.hd,你会得到剩余的行。也许您可以使用折叠来重复应用它并收集结果。

    【讨论】:

      【解决方案2】:

      假设您的列表是矩形的,this Standard ML code 会转换为 OCaml:

      let rec transpose xss =
          match xss with
              | [] -> []
              | []::_ -> []
              | _ -> List.map List.hd xss :: transpose (List.map List.tl xss)
      

      在删除已提取的列 (List.map List.tl xss) 后,它提取第一列 (List.map List.hd xss) 并递归地将其与其余列的提取相结合。

      仍然保留在此函数中的显式递归不能轻易地被映射/折叠替换,因为它们将一次寻址一行,而上面的递归方案一次寻址(一部分)所有行。 unfolding / anamorphism 你可能会更幸运:

      let rec unfold f a =
          match f a with
          | Some (b, a') -> b :: unfold f a'
          | None -> []
      
      val unfold : ('a -> ('b * 'a) option) -> 'a -> 'b list = <fun>
      

      'a 可能是输入行矩阵的逐渐减少,'b 矩阵列:

      let transpose =
          unfold (function
                  | [] -> None
                  | []::_ -> None
                  | m -> Some (List.map List.hd m, List.map List.tl m))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-14
        • 1970-01-01
        • 1970-01-01
        • 2019-10-04
        • 1970-01-01
        • 2023-04-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多