我正在做一些家庭作业,但我在某件事上被困了几个小时。 我确信这真的很微不足道,但在仔细阅读了所有可用的文档后,我仍然无法理解它。 有人可以帮我吗? 基本上,OCaml 编程中的练习要求用平方算法求幂来定义函数 x^n。
我看过解决方案:
let rec exp x = function
0 -> 1
| n when n mod 2 = 0 -> let y = exp x (n/2) in y*y
| n when n mod 2 <> 0 -> let y = exp x ((n-1)/2) in y*y*x
;;
我特别不明白的是参数 n 如何从 fun 语句中省略以及为什么它应该用作与 x 匹配的变量,这与平方求幂的定义没有明显联系.
这是我的做法:
let rec exp x n = match n with
0 -> 1
| n when (n mod 2) = 1 -> (exp x ((n-1)/2)) * (exp x ((n-1)/2)) * x
| n when (n mod 2) = 0 -> (exp x (n/2)) * (exp x (n/2))
;;
最佳答案
您的版本在语法上是正确的,产生了一个很好的答案,但执行时间很长。
在您的代码中,exp
被递归调用两次,因此产生两倍的计算量,每次调用产生两倍的计算量,等等直到 n=0
。方案中,exp
只调用一次,结果保存在变量y
中,然后对y
求平方。
现在,关于语法,
let f n = match n with
| 0 -> 0
| foo -> foo-1
相当于:
let f = function
| 0 -> 0
| foo -> foo-1
行 let rec exp x = function
是一个函数的开头,该函数接受两个 参数:x
,并使用了一个未命名的参数在模式匹配中。在模式匹配中,行
| n when n mod 2 = 0 ->
将此参数命名为 n
。并不是说在模式匹配的每种情况下都可以使用不同的名称(即使那样不太清楚):
| n when n mod 2 = 0 -> let y = exp x (n/2) in y*y
| p when p mod 2 <> 0 -> let y = exp x ((p-1)/2) in y*y*x
关于functional-programming - 模式匹配中的变量如何允许参数省略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12996668/