Recursion 递归调用Ocaml上的For循环
我正在OCaml中实现素数分解。我不是一个函数式程序员;下面是我的代码。素数分解在素数部分函数中递归发生Recursion 递归调用Ocaml上的For循环,recursion,ocaml,primes,prime-factoring,Recursion,Ocaml,Primes,Prime Factoring,我正在OCaml中实现素数分解。我不是一个函数式程序员;下面是我的代码。素数分解在素数部分函数中递归发生primes是从0到num的primes列表。这里的目标是我可以在OCaml解释器中键入prime_部分,并在n=20,k=1时将其吐出 2 + 3 + 7 5 + 7 我从OCaml教程中改编了是素数和所有素数所有素数,以生成一个到b的素数列表 (* adapted from http://www.ocaml.org/learn/tutorials/99problems.html *) l
primes
是从0到num的primes列表。这里的目标是我可以在OCaml解释器中键入prime_部分,并在n=20,k=1时将其吐出
2 + 3 + 7
5 + 7
我从OCaml教程中改编了是素数
和所有素数
<在调用prime\u part
之前,需要调用code>所有素数,以生成一个到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)
下面是对您的代码的一些注释
List.iter
,而不会丢失对局部变量的访问prime\u part\u constructive
返回整数值的任何原因。在OCaml中,返回值()
,即所谓的“unit”,更为惯用。这是因其副作用(如打印值)而调用的函数返回的值a.(i)
用于访问数组,而不是列表。列表和数组在OCaml中不同。如果您将的替换为List.iter
,您就不必担心这一点
@
运算符。符号lst.concat
在OCaml中没有意义n
和一个整数列表,然后写出列表中每个元素乘以n
的值
let write_mults n lst =
let write1 m = Printf.printf " %d" (m * n) in
List.iter write1 lst
write1
函数是一个嵌套函数。请注意,它可以访问n
的值
let write_mults n lst =
let write1 m = Printf.printf " %d" (m * n) in
List.iter write1 lst
更新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 [] []
设素数\u部分n素数=
让rec走剩余k第一次累计=
如果剩余<0,则
累积
否则,如果剩余=0,则
累计
其他的
设f为p=
如果p int list->int list list=
#素数第12部分[2;3;5;7;11];;
-:int list=[[7;5];[7;3;2]]
请注意,此函数返回分区列表。这比写出来(IMHO)更有用(也更实用)。我在原始帖子中编辑了我的OCaml代码,以反映您建议的更改。当我将它放入OCaml解释器时,它正在轰炸函数h,因为它无法访问
lst
。它给了我一个未绑定值lst
错误。你知道为什么吗?你的函数h
没有被定义为嵌套函数。如果您想让它访问lst
,您需要在prime\u part\u constructive
中定义它。我将它移动到函数中(见上文)。但是,解释器说它找不到h
。那是因为我在使用它之前引用了它吗?如果是这样,我如何在不破坏prime\u part
的函数定义的情况下更改它。它仍然不在函数内部,现在它已经超过了另一侧的函数:-)我将编写一个嵌套函数的示例。啊哈!我相信我现在已将其更正为在函数中使用in
操作符。但是,现在我有一个错误此表达式的类型为'a->'b list->'c->'d,但表达式的类型应为int
。当我递归调用prime\u part
时,解释器在prime\u part n
下划线。在函数调用中可以有表达式吗?
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]]