【问题标题】:Convert from int list to int Ocaml从 int list 转换为 int Ocaml
【发布时间】:2017-05-26 12:39:16
【问题描述】:

如何从 int 列表中获取 number(int)?

示例:我有 int l=[1;2;3;4;5] 的列表,我想获取编号 n=54321

这是我的代码:

let rec number ls =
match ls with
    |[]->[]
    |(h::t)->h*10**(List.length t) +  number t
;;

当我编译它时,我得到这个错误:

错误:此表达式的类型为 int,但预期的表达式为 类型 浮动

【问题讨论】:

  • ** 只对浮点数起作用。( ** ) : float -> float -> float = .
  • 你可以考虑使用List.fold_right:List.fold_right (fun x acc -> x + acc * 10) [1; 2; 3; 4; 5] 0
  • @dkim 谢谢伙计,这解决了我的问题! :)
  • 或 fold_left tail-rec 版本:List.fold_left (fun (acc,pow) x -> (x * pow + acc), pow*10) (0,1) [1;2 ;3;4;5] |> fst;;

标签: list ocaml


【解决方案1】:

最简单的方法是以尾递归的方式使用迭代器

List.fold_left f a [b1; ...; bn] is f (... (f (f a b1) b2) ...) bn.

let number_tr ls = 
  let n, _ = List.fold_left (
    fun (n, pow) e -> (e * pow + n, pow * 10) (0, 1) ls in
  ls

累加器包含两个整数,我们正在计算的数字和实际功率。对于每个新元素,我们将数字递增,然后将数字乘以 10。

另一个版本使用非尾递归迭代器

List.fold_right f [a1; ...; an] b is f a1 (f a2 (... (f an b) ...))

let number_ntr ls = 
  List.fold_right (fun e n -> e + n * 10) ls 0

运行:

number_tr [1; 2; 3]
> acc = (0, 1), e = 1 -> new acc = (1 * 1 + 0, 1 * 10)
  > acc = (1, 10), e = 2 -> new acc = (2 * 10 + 1, 10 * 10)
    > acc = (21, 100), e = 3 -> new acc = (3 * 100 + 21, 100 * 10)
      > acc = (321, 1000) -> returns 321

number_ntr [1; 2; 3]
> acc = 0, e = 3 -> new acc = 3 + 0 * 10
  > acc = 3, e = 2 -> new acc = 2 + 3 * 10
    > acc = 32, e = 1 -> new acc = 1 + 32 * 10
      > acc = 321 -> returns 321

【讨论】:

    【解决方案2】:

    你也可以使用尾递归:

    let f l = 
        let rec f_helper l num =
            match l with 
            | [] -> num
            | (h::t) -> f_helper t ((num * 10 ) + h)
        in f_helper (List.rev l) 0
    ;;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 2013-01-01
      • 1970-01-01
      • 2015-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多