【问题标题】:How to add 2 Matrices together in OCAML without modules?如何在没有模块的情况下在 OCAML 中将 2 个矩阵相加?
【发布时间】:2020-02-19 23:38:35
【问题描述】:

我制作了一个函数来检查有效矩阵,一个函数可以找到列表的长度 strong> 和一个函数,它表示矩阵中的行长列数。我需要知道的是如何编写一个函数,将两个矩阵相加没有模块。我将在下面展示已完成的功能

(* declaration of types intseq and intmatrix *)
type intseq = int list;;

type intmatrix = IM of intseq list;;

let getbody (IM x) = x;;

(* function getbody to retrieve the body of the intmatrix which is of type intseq list *)

let rec length: 'a list -> int =
  fun xs ->
  match xs with
    [] -> 0
  | (x::rest) -> 1 + length rest;;

(* test whether a list of lists of integers represents a matrix. 
   The length of each row should be equal.*)
let rec ismatrix x =

  match x with
    | IM([]) -> true
    | IM([[]]) -> true
    | IM([_]) -> true
    | IM(x::x2::rest) -> if (length x <> length x2)
        then false
        else ismatrix (IM(x2::rest));;

(* function matrixshape takes the matrix, and calculates the number of
   columns and rows *)
let rec matrixshape x =
  match x with
    | IM([]) -> (0,0)
    | IM([[]]) -> (0,0)
    | IM(x::rest) -> (length x,length rest + 1);;



(*A couple of extra functions I tried out \/ \/ \/*)
let rec seqadd : intseq -> intseq -> intseq =
  fun xs ys ->
  begin match xs, ys with
  | [], _ -> ys
  | _, [] -> xs
  | h::t, h2::t2 -> (h+h2)::(seqadd t t2)
  end;;

let rec rowadd: intseq list -> intseq list -> intseq list =
  fun row1 row2 ->
  match row1, row2 with
    | IM([[]]), IM([[_]]) -> row1
    | IM([[_]]), IM([[]]) -> row2
    | IM([[h::t]]), IM([[h2::t2]]) -> IM([[(h+h2)::(rowadd t t2)]]);;


(* matrix addition *)
let rec matrixadd: intmatrix -> intmatrix -> intmatrix =
  fun x y ->
(*TO DO*)

【问题讨论】:

  • “没有模块”是什么意思?你的意思是没有标准库?你能告诉你卡在哪里,为什么你不能完成它吗?也许你会如何“使用模块”来做到这一点。
  • @ThéoWinterhalter 我不允许使用“List”等库函数。
  • 你是怎么做到的?请向我们展示您是如何尝试编写函数的。
  • 对。但是是什么让你卡住了?是不是不知道矩阵加法的定义?
  • OCaml 不是“声明性”语言。它是基于表达式而不是基于语句的,但仍然支持函数式和命令式编程。无论如何,你必须更具体。向我们展示您尝试解决问题的一些代码,并解释您正在努力解决的具体问题。这使 su 了解您理解和不理解的内容,因为我们无法在答案中很好地向您解释整个语言。我们也不打算只为您编写代码,因为您不会从中学到任何东西。

标签: matrix ocaml addition ml


【解决方案1】:

我会把它分解成几个更简单的步骤,就像你开始做的那样——添加一行,然后添加多行,例如。

let matrixadd m1 m2 =
  let rec addrow r1 r2 =
    match r1,r2 with
    | x :: x',  y :: y' -> x + y :: addrow x' y'
    | _                 -> []                     (* assume dims are correct *)
  in
  let rec addrows a b =
    match a,b with
    | r1 :: a', r2 :: b' -> addrow r1 r2 :: addrows a' b'
    | _                  -> []
  in
  let a, b = getbody m1, getbody m2 in
  IM (addrows a b)


(* example *)
let m1 = IM [[1;2]; [3;4]] in matrixadd m1 m1;;
(* - : intmatrix = IM [[2; 4]; [6; 8]] *)

【讨论】:

  • 看看如何将addrowsaddrow 合并成一个函数。只是因为我认为这对你来说会很有趣 =)
【解决方案2】:

如果您确定输入矩阵的大小相同,则可以使用以下函数。
它是为 matrix = int list list 实现的。

let add = 
  let rec add f a b = 
    match a, b with 
    | ah :: at, bh :: bt -> (f ah bh) :: (add f at bt)
    | [], []             -> []
    | _                  -> assert false
  in
  add (add (+)) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 2017-06-14
    • 2019-08-15
    • 1970-01-01
    • 2021-10-12
    • 2013-04-17
    相关资源
    最近更新 更多