我自己教授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;这样做的方式。
答案 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
被分解为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)
这里的想法是返回10
,100
,1000
...等等,以了解最后一位数的位置。
我想在这里做的就是对待它们,因为我会处理列表,decompose_int
是List.hd
和List.tl
等价物。