在SML中创建最多为给定n值的素数列表

时间:2018-01-14 08:04:22

标签: recursion sml

我最近开始学习SML,并且我的任务是创建一个素数列表,直到用户输入的n值。我已经被困了几个小时玩各种可能的解决方案,我现在在这里,下标超出界限错误:

fun primes(n) = 
let
  val lst = tl(makeLst(n))
  val k = 0
  fun recurse(lst,k) = 
    if k > n then lst
    else recurse(removeMult(lst, List.nth(lst,k)), k+1)
in
  recurse(lst,k)
end;

我认为错误来自于我使用List.nth(),虽然我不确定是否有另一种方法来获取removeMult函数所需的索引。任何帮助将非常感谢!!谢谢。

1 个答案:

答案 0 :(得分:4)

recurse的递归期间,参数列表会变短,所以如果尝试运行n,当然会失败。诀窍不是递归到某些n,而是直到你到达列表的末尾。

这里还有另一个问题:你用0开始recurse。一切都是1的倍数,所以事实上,第二次递归时列表将变为空。

最后,您的makeLst函数虽然在语义上是正确的,但效率很低。附加到列表和列表必须复制整个列表。您应该尝试在开始时扩展列表。否则该函数具有二次复杂度。

以下是我编写此代码的方法:

fun enum (n, m) = if n > m then [] else n :: enum (n+1, m)
fun sieve [] = []
  | sieve (n::ns) = n :: sieve (List.filter (fn m => m mod n > 0) ns)
fun primes n = sieve (enum (2, n))