2015-08-15 89 views
0

我确定有一种方法可以在SML中优雅地完成此操作,但我很难记录迭代次数(基本上是我的函数被调用的次数)。SML:跟踪迭代次数

我试图写一个函数来计算一对数字,一个用于答案的底部,另一个用于剩下的部分。所以,如果你叫:

divmod(11, 2),你会得到(5, 1)回来。

这是我到目前为止有:

divmod(number : int, divisor : int) = 
    if number < divisor then 
     (number, count) 
    else 
     divmod(number - divisor, divisor); 

很显然,我还没有建立我的计数变量,所以它不会编译但是这是算法的思想。剩下的就是将count初始化为0,并能够在递归调用之间传递它。但是我只允许这个函数的两个参数。

但是,我可以编写辅助功能。

想法?

+0

不SML允许嵌套函数?在这种情况下,您可以使用它来传递count参数。 – Christian

回答

1

如果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) 
+0

我想我可以开玩笑地定义该函数外部使用divmod,然后在divmod中调用它,不是吗?另外,你的最后一行是做什么的? – bclayman

+0

是的,你可以在'divmod'之外定义'_divmod',如果你喜欢并且从后者调用前者。 最后一行使用从外部函数传递的值加上'count'的初始值(它是零)来调用嵌套函数。 – Christian

1

就个人而言,我喜欢事实,SML不是纯粹的功能性语言。跟踪函数调用自然是通过副作用完成的(而不是显式传递一个计数器变量)。

例如,给定一个通用的递归斐波那契:

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 fib 0 = 0 
| fib 1 = 0 
| fib n = 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 

(其中,顺便说一下,说明了为什么这个版本的斐波那契的递归的不是很好!)