【发布时间】:2015-11-08 17:59:56
【问题描述】:
我正在尝试在 SML 中实现乘法,但有一些限制。我得到了以下add 函数:
fun add (0 : int, m : int) : int = m
| add (n : int, m : int) : int = 1 + add(n-1, m)
我正在尝试编写一个函数,以便 mult (m, n) 递归地计算 m 和 n 的乘积,对于任意两个自然数 m 和 n。你的实现可以使用上面提到的函数add和-(减法),但不能使用+或*。
这是我的尝试:
fun multiply(0 : int, m : int) = 0
| multiply(n : int, 0 : int) = 0
| multiply(1 : int, m : int) = m
| multiply(n : int, 1 : int) = n
| multiply(~1 : int, m : int) = ~m
| multiply(n : int, ~1 : int) = ~n
| multiply(n : int, m : int) =
if (n > 0 andalso m > 0) then
add(add(0, n), multiply(n, m - 1))
else
if (n < 0 andalso m < 0) then
multiply(~n, ~m)
else
if (n < 0 andalso m > 0) then
n - multiply(n, m - 1)
(* n > 0 and m < 0 *)
else
m - multiply(m, n - 1);
当n 和m 都为正数或均为负数时有效,但当一个为正数另一个为负数时无效,但我似乎无法找出我的错误。例如,
multiply(3, ~10) 计算结果为 0。所以我认为我的递归调用正在到达0 并导致它评估为0。话虽如此,我的基本案例已经解决了这个问题,所以我不确定这怎么可能。
想法?
【问题讨论】:
-
也许将
m - multiply(m, n - 1);更改为m - multiply( n - 1,m);?递归可能搞砸了?接触 SML 已经 4 年了,抱歉我不能更有用了 -
@Parker 你为什么这么建议? (不是说错了,但也对你的推理感兴趣)
-
快速浏览一下,您似乎正在根据正负两个值来处理事情,如果您不断递归并且 n 和 m 不断变化点,则可能会弄乱逻辑。就像函数总是期望 (n,m) 一样,但您传递的是 (m,n)。同样,我可能忘记了 SML 函数
-
为什么 n 和 m 一直在换位置?
-
啊,我明白你在说什么。是的,我无意中翻转了它们,尽管我在调用 multiply(~3, 10) 时仍然遇到同样的问题,呵呵
标签: recursion functional-programming sml smlnj