我正在研究OCaml中的主要分解的实现。我不是一名功能性程序员;以下是我的代码。主要分解在prime_part函数中递归地发生。 primes
是从0到num的素数列表。这里的目标是我可以将prime_part键入OCaml解释器并在n = 20,k = 1时将其吐出。
2 + 3 + 7
5 + 7
我从OCaml教程中调整了is_prime
和all_primes
。在all_primes
被调用之前,需要调用b
来生成最多prime_part
的素数列表。
(* 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
答案 0 :(得分:1)
以下是对您的代码的一些评论。
您可以在OCaml中定义嵌套函数。嵌套函数可以访问所有先前定义的名称。因此,您可以使用List.iter
而不会失去对本地变量的访问权限。
我没有看到您的函数prime_part_constructive
返回整数值的任何原因。在OCaml中返回值()
(称为&#34; unit&#34;)将更加惯用。这是为其副作用(例如打印值)调用的函数返回的值。
符号a.(i)
用于访问数组,而不是列表。 OCaml中的列表和数组不同。如果您将for
替换为List.iter
,则您不必担心这一点。
要连接两个列表,请使用@
运算符。在OCaml中,符号lst.concat
没有意义。
<强>更新强>
以下是它具有嵌套功能的方式。这个组成函数需要一个n
和一个整数列表,然后写出列表中每个元素的值乘以n
。
let write_mults n lst =
let write1 m = Printf.printf " %d" (m * n) in
List.iter write1 lst
write1
函数是嵌套函数。请注意,它可以访问n
。
更新2
这是我写这个函数时得到的:
let prime_part n primes =
let rec go residue k lst accum =
if residue < 0 then
accum
else if residue = 0 then
lst :: accum
else
let f a p =
if p <= k then a
else go (residue - p) p (p :: lst) a
in
List.fold_left f accum primes
in
go n 1 [] []
它适用于您的示例:
val prime_part : int -> int list -> int list list = <fun>
# prime_part 12 [2;3;5;7;11];;
- : int list list = [[7; 5]; [7; 3; 2]]
请注意,此函数返回分区列表。这比写出来更有用(和功能性)(恕我直言)。