首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将OCaml中的两个列表相加

将OCaml中的两个列表相加
EN

Stack Overflow用户
提问于 2013-11-28 15:54:33
回答 1查看 2.1K关注 0票数 0

假设我们使用一个列表来反向表示数字,那么每个节点都是数字内部的一个数字。

所以[1;2;3;4;5]是数字54321

现在我们想把两个这样的列表加起来,例如,添加1;2和3;4,得到4;6,即64。

这是我的代码:

代码语言:javascript
复制
let add l1 l2 =
  let rec add_to up acc = function
    | [] -> if up = 1 then 1::acc else acc
    | hd::tl -> 
      let s = hd+up in
      if s >= 10 then add_to 1 ((s-10)::acc) tl
      else List.rev_append tl (s::acc)
  and 
  add_up up acc = function
    | [], [] -> if up = 1 then 1::acc else acc
    | l, [] | [], l -> (add_to up [] l) @ acc
    | hd1::tl1, hd2::tl2 ->
      let s = hd1+hd2+up in
      if s >= 10 then add_up 1 ((s-10)::acc) (tl1, tl2)
      else add_up 0 (s::acc) (tl1, tl2)
  in 
  List.rev (add_up 0 [] (l1, l2))

这个想法非常简单,从两个列表中添加两个hds,如果两个hds之和大于或等于10,则将1带到下一个。

然而,我认为我的代码看起来并不漂亮。

  1. 我们有多余的部分逻辑来解决进位问题。
  2. 我必须在两个列表上做@

有人能帮我把它弄得更漂亮吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-28 17:24:44

我认为诀窍是概括。其实质是增加三件事,而不是两件事。

代码语言:javascript
复制
let sum a b =
    let rec isum a b c =
        match a, b with
        | [], [] -> if c = 0 then [] else [c]
        | [], x | x, [] -> isum [0] x c
        | ah :: at, bh :: bt ->
            let s = ah + bh + c in
            (s mod 10) :: isum at bt (s / 10)
    in
    isum a b 0

此代码不是尾递归的。尾部递归版本会稍微不那么优雅。

注意:我假设您使用[]来表示0。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20270304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档