我必须编写一个递归函数来计算数字的乘积。我写下的是:
let rec digits_product x =
if x = 0 then 0
else
let n = x mod 10 in
n * digits_product (x / 10)
问题是它总是返回0。我确信我错过了一些东西,但我找不到。你能帮我解决这个问题吗?该代码应该计算数字的数字乘积,例如,如果我输入 12345,它应该返回 12345,等于 120。
更新
我将代码更改为:
let rec digits_product x =
match x with
| 0 -> 0
| 1 -> 1
| 2 -> 2
| 3 -> 3
| 4 -> 4
| 5 -> 5
| 6 -> 6
| 7 -> 7
| 8 -> 8
| 9 -> 9
| _ -> (x mod 10) * digits_product (x / 10)
现在可以了,但我还有一个问题:有没有更有效的方法?
您的代码始终会进行递归调用,除非参数
x
为 0。由于它没有显示无限递归的迹象,因此您知道它至少返回 0 一次。这应该足以表明出了什么问题。
更新
您正在检查输入是否为 0,因为在这种情况下答案是显而易见的。但还有其他输入,答案是显而易见的。即,您不需要进行任何乘法即可获得结果。为什么不检查所有这些呢?您只需一次测试即可检查所有这些值。
IMO,语法看起来会更干净,如下所示:
let rec produsul_cifrelor x =
match x with
| n when n < 10 -> n
| _ -> (x mod 10) * produsul_cifrelor (x/10)
然后运行
produsul_cifrelor 12345
将返回120
。
其他答案已经确定了该问题,但这可以提供分解问题的示例。 首先让我们获取一个数字的数字。
# let rec digits n =
if n < 10 then [n]
else (n mod 10) :: digits (n / 10);;
val digits : int -> int list = <fun>
# digits 1234;;
- : int list = [4; 3; 2; 1]
然后我们只需要一个
product
函数,该函数很容易编写,然后应用于 digits
的结果。
# let rec product =
function
| [] -> 1
| x::xs -> x * product xs;;
val product : int list -> int = <fun>
# product @@ digits 1234;;
- : int = 24
# let product_digits n = product @@ digits n;;
val product_digits : int -> int = <fun>
# product_digits 12345;;
- : int = 120
product
功能可以实现为左折叠。这展示了我们如何独立地实现问题的这两部分,只要它们的类型保持一致。
# let product = List.fold_left ( * ) 1;;
val product : int list -> int = <fun>
# product @@ digits 234;;
- : int = 24