【问题标题】:How to apply an aritmethic operation over each element in the list of lists containing integers?如何对包含整数的列表列表中的每个元素应用算术运算?
【发布时间】:2020-04-10 00:54:19
【问题描述】:

我想知道如何编写一个函数,该函数将接受两个参数,即 a' 和 b'(它们是函数),以及一个列表列表;

然后,如果 int 列表(我的意思是包含整数)列表中的任何列表中的元素之和是奇数,它将执行乘法运算 - 函数 a' (乘以相同的整数 -> x * x),在该列表中的每个元素上。

否则,如果 int-lists 列表中任何列表中的元素之和为偶数,它将执行加法运算 - 函数 b' (添加。使用相同的整数 -> x + x),在该列表中的每个元素上。

因此,带有输入的函数调用将是:

func a b [[1;3];[8;3]];;

...然后输出应如下所示:

- : int list list = [[2; 6]; [64; 9]]

第一个列表的元素总和是偶数,所以第一个列表会被相加 第二个列表中元素的和为奇数,表示第二个列表将被相乘。

我在 Ocaml 中编写了这个函数作为练习,我真的很难理解这种语言;我想知道我做错了什么... 此外,我们将不胜感激战略帮助! - 也就是说,对事物如何的解释 实际上在 Ocaml 中工作,虽然我对 Ocaml 并不完全是新手,但我已经学到了很多关于尾递归函数的知识,只是函数之间的参数交换让我很困扰。

好的,代码如下:

let a = List.map (List.fold_left ( + ) 0)
let b = List.map (List.fold_left ( * ) 0)

let rec func a b lists = if lists = [] then []

             else if ((List.map (List.fold_left ( + ) 0)) mod 2 = 0) then List.map
                     (List.fold_left ( + ) 0)
             else List.map (List.fold_left ( * ) 0)

(* Function call: *)
func (fun x -> x*x) (fun x -> x+x) [[1;3];[5;7]];;

【问题讨论】:

    标签: matrix ocaml tail-recursion


    【解决方案1】:

    您正在处理这里的列表列表。所以你需要List.map列表列表,还有List.map每个单独的列表。

    当您执行List.map (List.fold_left ( + ) 0) 时,您将部分应用到两个功能:
    对于List.fold_left,您给出要应用的函数和初始元素,并留下一个仍然采用列表的函数。
    对于List.map,给出了第一个参数(要应用的函数),最终得到的函数仍将获取列表列表:所以在这一点上,它仍然是一个未评估的函数。你不能用它做mod 2,因为你没有整数。

    您在顶部定义的ab 并未实际使用,因为它们会被func 中的函数参数所遮蔽。
    当您拨打func (fun x -> x*x) (fun x -> x+x) [[1;3];[5;7]];; 时,a 将是(fun x -> x*x)b 将是(fun x -> x+x),而您的lists 将是[[1;3];[5;7]]

    您的func 不是递归函数,它不会调用自身。您使用的 List.map 不是尾递归,而 List.fold_left 是。
    见:
    https://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html#VALmap
    https://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html#VALfold_left
    这可能有助于理解尾递归:https://www.cs.cornell.edu/courses/cs3110/2020sp/textbook/data/tail_recursion.html

    我会尽量将您的代码更改为:

    let func a b lists = 
      let is_even l = List.fold_left ( + ) 0 l mod 2 = 0 in
      List.map (fun l -> if is_even l then List.map b l else List.map a l) lists
    
    (* Function call: *)
    let _ = func (fun x -> x*x) (fun x -> x+x) [[1;4];[5;7]]
    

    它映射列表列表,所以l 是一个列表。然后它检查该列表的总和是否为偶数,如果是,则将函数 b 应用于每个单独的元素,否则将 a

    编辑: 如果你想让它尾递归,你可以用List.rev_map切换出List.map,然后用List.rev反转映射列表。

    【讨论】:

      猜你喜欢
      • 2020-07-16
      • 1970-01-01
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多