【发布时间】:2017-02-08 23:05:50
【问题描述】:
我正在研究 OCaml 中素数分解的实现。我不是函数式程序员;下面是我的代码。素数分解在 prime_part 函数中递归发生。 primes 是从 0 到 num 的素数列表。这里的目标是我可以在 OCaml 解释器中输入 prime_part 并在 n = 20, k = 1 时将其吐出。
2 + 3 + 7
5 + 7
我改编自 OCaml 教程中的 is_prime 和 all_primes。在调用prime_part 之前,需要调用all_primes 以生成直到b 的素数列表。
(* adapted from http://www.ocaml.org/learn/tutorials/99problems.html *)
let is_prime n =
let n = abs n in
let rec is_not_divisor d =
d * d > n || (n mod d <> 0 && is_not_divisor (d+1)) in
n <> 1 && is_not_divisor 2;;
let rec all_primes a b =
if a > b then [] else
let rest = all_primes (a + 1) b in
if is_prime a then a :: rest else rest;;
let f elem =
Printf.printf "%d + " elem
let rec prime_part n k lst primes =
let h elem =
if elem > k then
append_item lst elem;
prime_part (n-elem) elem lst primes in
if n == 0 then begin
List.iter f lst;
Printf.printf "\n";
()
end
else
if n <= k then
()
else
List.iter h primes;
();;
let main num =
prime_part num 1 [] (all_primes 2 num)
我很困惑 for 循环的隐蔽性。我看到 List.ittr 是 OCaml 方式,但是如果我为 List.ittr 定义另一个函数,我将无法访问我的变量。我需要访问这些变量以递归调用 prime_part。有什么更好的方法来做到这一点?
我可以用 Ruby 表达我想用 OCaml 完成什么。 n = 任意数,k = 1,lst = [],primes = 素数 0 到 n 的列表
def prime_part_constructive(n, k, lst, primes)
if n == 0
print(lst.join(' + '))
puts()
end
if n <= k
return
end
primes.each{ |i|
next if i <= k
prime_part_constructive(n - i, i, lst+[i], primes)
}
end
【问题讨论】:
标签: recursion ocaml primes prime-factoring