在数组列表 OCaml 中乘以 int

Multiply int in array list OCaml

我正在尝试在 OCaml 中解决这个问题:

我有两个可变大小的数组,例如 [1;4;5][3;2;3],它们代表两个整数:145 和 323。

我想将这两个数字相乘 145 * 323。结果是46835。我想在数组 [4;6;8;3;5].

中得到结果

对整数列表进行数学计算会让人头疼,所以首先要弄清楚如何定义两个列表的乘法。我将假设它们将始终是整数并定义一个函数如下。

let mult_int_lists a b =
    list_of_int ((int_of_list a) * (int_of_list b));;

该函数接受两个列表,将它们转换为整数,将它们相乘,然后将结果转换回列表。那么我们如何定义list_of_intint_of_list呢?在查看我的代码之前,我会挑战你自己解决这个问题。

let int_of_list l =
    let rec exp x = if x = 0 then 1 else 10 * (exp (x - 1)) in
    List.fold_left (+) 0 (List.mapi (fun i x -> x * (exp i)) (List.rev l))

将列表转换为 int 需要我们反转列表,将每个数字乘以 10^i,然后将所有这些数字相加。我使用 List.rev 将列表按从小到大的顺序排列。然后 List.mapi 取每个值并将其转换为正确的十位。最后,List.fold_left 获取值列表并将它们添加到单个整数值中。

let list_of_int i =
    let rec aux i =
        if i = 0 then [] else (i mod 10) :: aux (i / 10) in
    List.rev (aux i)

要将 int 转换为列表,我们需要通过除以 10 得到每个十位,只保留余数。要获得余数,我们可以使用 modulus (mod)。然后我们可以继续循环直到数字等于零,这就是我们 return 列表值的时候。它将向后,所以这就是为什么使用 List.rev。

您需要做的第一件事是将代表一个整数的整数列表转换为整数本身。使用整数的基数 10 表示来创建这样的函数。一个简单的例子是整数 145 : 100 * 1 + 10 * 4 + 5。所以第一个函数看起来像:

   let list_to_int l =
  List.fold_left (fun (acc,n) x ->
     let m = 10. ** (n -. 1.) in
     acc +. x *. m, n -. 1.
    ) (0.0, float_of_int (List.length l)) l
;;

我使用函数 fold_left 来累加整数值,我还使用函数 pow(记住以 10 为底)。

您需要的第二个函数是从整数中获取数字。您将拥有这样的功能:

        val digits : int -> int list = <fun>

有了这个函数(写成练习!),你就会得到最终的结果。示例:

digits 46835;;
- : int list = [4; 6; 8; 3; 5]

最后,您有以下函数进行乘法运算:

let mul l1 l2 =
  let (x1,_) = list_to_int (List.map float_of_int l1)in 
  let (x2,_) = list_to_int (List.map float_of_int l2) in 
  digits ((int_of_float x1) * (int_of_float x2));;

您需要将整数列表转换为浮点数,因为函数 pow 适用于类型 float。希望对您有所帮助!