在OCaml中反转int

时间:2015-07-12 16:05:28

标签: functional-programming ocaml

我自己教授OCaml,而我用于练习的主要资源是康奈尔从3110课程中提供的一些问题集。其中一个问题是编写一个反转int的函数(即:1234 - > 4321,-1234 - > -4321,2 - > 2,-10 - > -1等)。

我有一个有效的解决方案,但我担心它不完全是惯用的OCaml:

let rev_int (i : int) : int =
  let rec power cnt value =
    if value / 10 = 0 then cnt 
    else power (10 * cnt) (value/10) in
  let rec aux pow temp value =
    if value <> 0 then aux (pow/10) (temp + (value mod 10 * pow)) (value / 10)
    else temp in
  aux (power 1 i) 0 i

据我所知,它在所有情况下都能正常工作,但它看起来很严肃,而且非正式使用#34;对我来说,特别是因为我用两个内部函数运行int的长度两次。所以我只是想知道是否还有更多&#34; OCaml&#34;这样做的方式。

2 个答案:

答案 0 :(得分:4)

我想说,以下是足够的惯用语。

(* [rev x] returns such value [y] that its decimal representation
   is a reverse of decimal representation of [x], e.g., 
   [rev 12345 = 54321] *)
let rev n = 
  let rec loop acc n =
    if n = 0 then acc 
    else loop (acc * 10 + n mod 10) (n / 10) in
  loop 0 n

但正如杰弗里在评论中所说,你的解决方案非常惯用,虽然不是最好的解决方案。

是的,我自己的风格,就是这样写:

let rev n = 
  let rec loop acc = function
    | 0 -> acc
    | n -> loop (acc * 10 + n mod 10) (n / 10) in 
  loop 0 n

因为我更喜欢与if/then/else进行模式匹配。但这是我个人品味的问题。

答案 1 :(得分:1)

我可以为你提供一些方法:

let decompose_int i =
  let r = i / 10 in
  i - (r * 10) , r

这个函数允许我分解整数,好像我有一个列表。 例如,1234被分解为4123。 然后我们逆转它。

let rec rev_int i = match decompose_int i with
  | x , 0 -> 10 , x
  | h , t ->
    let (m,r) = rev_int t in
    (10 * m, h * m + r)

这里的想法是返回101001000 ...等等,以了解最后一位数的位置。

我想在这里做的就是对待它们,因为我会处理列表,decompose_intList.hdList.tl等价物。