在 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
被分解为4
和123
。
然后我们反过来。
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_int
是 List.hd
和 List.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
。但这是我个人口味的问题。
我正在自学 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
被分解为4
和123
。
然后我们反过来。
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_int
是 List.hd
和 List.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
。但这是我个人口味的问题。