SML:跟踪迭代次数
SML: Keeping track of number of iterations
我确信有一种方法可以在 SML 中优雅地执行此操作,但我很难跟踪迭代次数(基本上是我的函数被调用的次数)。
我正在尝试编写一个计算结果为一对数字的函数,一个代表答案的底数,另一个代表余数。因此,如果您致电:
divmod(11, 2)
,你会得到 (5, 1)
。
这是我目前的情况:
divmod(number : int, divisor : int) =
if number < divisor then
(number, count)
else
divmod(number - divisor, divisor);
显然,我没有设置我的计数变量,所以它不会编译,但这就是算法的想法。剩下的就是将 count 初始化为 0 并能够在递归调用之间传递它。但是我只允许这个函数的两个参数。
不过,我可以编写辅助函数。
想法?
如果 SML 支持嵌套函数,您可以这样做:
divmod(number : int, divisor : int) =
_divmod(n : int, d : int, count : int) =
if n < d then
(count, n)
else
_divmod(n - d, d, count + 1)
_divmod(number, divisor, 0)
就个人而言,我 喜欢 SML 不是纯函数式语言这一事实。跟踪函数调用自然是通过副作用完成的(而不是显式传递计数器变量)。
例如,给定一个通用的递归斐波那契数列:
fun fib 0 = 0
| fib 1 = 0
| fib n = fib(n-2) + fib(n-1);
您可以修改它,以便每次调用它时都会增加一个计数器作为副作用:
counter = ref 0;
fun fib 0 = (counter := !counter + 1; 0)
| fib 1 = (counter := !counter + 1; 1)
| fib n = (counter := !counter + 1; fib(n-2) + fib(n-1));
您可以直接使用它,也可以稍微包装一下:
fun fibonacci n = (
counter :=0;
let val v = fib n
in
(!counter,v)
end);
典型的运行:
- fibonacci 30;
val it = (2692537,832040) : int * int
(顺便说一下,这说明了为什么这个版本的斐波那契递归不是很好!)
我确信有一种方法可以在 SML 中优雅地执行此操作,但我很难跟踪迭代次数(基本上是我的函数被调用的次数)。
我正在尝试编写一个计算结果为一对数字的函数,一个代表答案的底数,另一个代表余数。因此,如果您致电:
divmod(11, 2)
,你会得到 (5, 1)
。
这是我目前的情况:
divmod(number : int, divisor : int) =
if number < divisor then
(number, count)
else
divmod(number - divisor, divisor);
显然,我没有设置我的计数变量,所以它不会编译,但这就是算法的想法。剩下的就是将 count 初始化为 0 并能够在递归调用之间传递它。但是我只允许这个函数的两个参数。
不过,我可以编写辅助函数。
想法?
如果 SML 支持嵌套函数,您可以这样做:
divmod(number : int, divisor : int) =
_divmod(n : int, d : int, count : int) =
if n < d then
(count, n)
else
_divmod(n - d, d, count + 1)
_divmod(number, divisor, 0)
就个人而言,我 喜欢 SML 不是纯函数式语言这一事实。跟踪函数调用自然是通过副作用完成的(而不是显式传递计数器变量)。
例如,给定一个通用的递归斐波那契数列:
fun fib 0 = 0
| fib 1 = 0
| fib n = fib(n-2) + fib(n-1);
您可以修改它,以便每次调用它时都会增加一个计数器作为副作用:
counter = ref 0;
fun fib 0 = (counter := !counter + 1; 0)
| fib 1 = (counter := !counter + 1; 1)
| fib n = (counter := !counter + 1; fib(n-2) + fib(n-1));
您可以直接使用它,也可以稍微包装一下:
fun fibonacci n = (
counter :=0;
let val v = fib n
in
(!counter,v)
end);
典型的运行:
- fibonacci 30;
val it = (2692537,832040) : int * int
(顺便说一下,这说明了为什么这个版本的斐波那契递归不是很好!)