在 OCaml 中反转一个 int

Reversing an int in OCaml

我正在自学 OCaml,我用于练习的主要资源是康奈尔大学从他们的 3110 class 中提供的一些问题集。其中一个问题是编写一个函数来反转 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

据我所知,它在所有情况下都能正常工作,但它对我来说似乎很严重 "un-OCaml",特别是因为我 运行 通过 int 的长度两次,两个内部功能。所以我只是想知道是否有更多 "OCaml" 的方法来做到这一点。

我可以建议你一些方法:

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)

这里的思路是return 10, 100, 1000...等知道最后一位放在哪里


我想在这里做的是像对待列表一样对待它们,decompose_intList.hdList.tl 的等价物。

我会说,以下内容足够地道。

(* [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

但正如 Jeffrey 在评论中所说,您的解决方案非常地道,尽管不是最好的解决方案。

顺便说一句,我自己的风格是这样写的:

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。但这是我个人口味的问题。