我写了这个函数来计算一个数字的回文:
let palindrome n =
let mutable current = n
let mutable result = 0
while(current > 0) do
result <- result * 10 + current % 10
current <- current / 10
result
Run Code Online (Sandbox Code Playgroud)
我怎样才能以更实用的方式重写它?
目前还不清楚你想做什么.palindrome给定的函数只是反转整数的数字:
> palindrome 1;;
val it : int = 1
> palindrome 12;;
val it : int = 21
> palindrome 123;;
val it : int = 321
> palindrome 9852;;
val it : int = 2589
Run Code Online (Sandbox Code Playgroud)
那些不是回文数字,但让我们把问题分成更小的构建块.
您可以轻松地将整数拆分为数字列表.实际上,拆分成反向数字列表是我能想到的最简单的方法:
let rec revdigits i =
let tens = i / 10
if tens = 0
then [i]
else
let ones = i % 10
ones :: revdigits tens
Run Code Online (Sandbox Code Playgroud)
这是类型的函数int -> int list.
例子:
> revdigits 1;;
val it : int list = [1]
> revdigits 12;;
val it : int list = [2; 1]
> revdigits 123;;
val it : int list = [3; 2; 1]
> revdigits 9852;;
val it : int list = [2; 5; 8; 9]
Run Code Online (Sandbox Code Playgroud)
将数字列表连接成一个数字也很容易:
let rec concat digits =
match digits with
| [] -> 0
| h :: t -> h * int (10. ** float t.Length) + concat t
Run Code Online (Sandbox Code Playgroud)
此功能具有类型int list -> int.
例子:
> concat [1];;
val it : int = 1
> concat [1; 2];;
val it : int = 12
> concat [1; 2; 3];;
val it : int = 123
> concat [2; 5; 8; 9];;
val it : int = 2589
Run Code Online (Sandbox Code Playgroud)
使用这些构建块,您可以轻松地组成一个与函数相同的palindrome函数:
let reverse = revdigits >> concat
Run Code Online (Sandbox Code Playgroud)
此功能具有类型int -> int.
例子:
> reverse 1;;
val it : int = 1
> reverse 12;;
val it : int = 21
> reverse 123;;
val it : int = 321
> reverse 2589;;
val it : int = 9852
Run Code Online (Sandbox Code Playgroud)
奖励:如果你不想反转数字,你可以这样做,但我不认为这个版本是尾递归的:
let rec digits i =
let tens = i / 10
if tens = 0
then [i]
else
let ones = i % 10
digits tens @ [ones]
Run Code Online (Sandbox Code Playgroud)
此功能具有类型int -> int list.
例子:
> digits 1;;
val it : int list = [1]
> digits 12;;
val it : int list = [1; 2]
> digits 123;;
val it : int list = [1; 2; 3]
> digits 9852;;
val it : int list = [9; 8; 5; 2]
Run Code Online (Sandbox Code Playgroud)
你可以使用尾递归函数来完成它.匹配值result:如果他的值= 0然后返回结果,否则执行计算current和result.
let palindrome n =
let rec rec_palindrome current result = match current with
| 0 -> result
| _ -> rec_palindrome (result * 10 + current % 10) (current / 10)
rec_palindrome n 0
Run Code Online (Sandbox Code Playgroud)
另外,在我的版本中,这不是可变值.