Recursion 使用递归的Erlang素数分解
我试图用素数分解来计算一个数的因子。我想使用if语句来测试条件,如果factor是factor,则创建一个列表。它不起作用,我想不出任何其他可行的方法,建议Recursion 使用递归的Erlang素数分解,recursion,erlang,factorization,Recursion,Erlang,Factorization,我试图用素数分解来计算一个数的因子。我想使用if语句来测试条件,如果factor是factor,则创建一个列表。它不起作用,我想不出任何其他可行的方法,建议 factor( N ) -> if N rem factor(N-1) == 0 -> [N|factor(N-1)]; true -> false; end. 这段代码进行分解,但我不使用if语句(在Erlang IMHO中不太常见): 我记录了一
factor( N ) ->
if
N rem factor(N-1) == 0 ->
[N|factor(N-1)];
true -> false;
end.
这段代码进行分解,但我不使用if语句(在Erlang IMHO中不太常见): 我记录了一个示例的执行跟踪。请注意,decomp/3是尾部递归的,因此长返回阶段实际上是单个返回
1> help_num:decomp(70610).
++ (3) <147> decomp(70610,[],2)
++ (4) <150> decomp(35305,[2],2)
++ (5) <151> decomp(35305,[2],3)
++ (6) <152> decomp(35305,[2],5)
++ (7) <150> decomp(7061,[5,2],5)
++ (8) <152> decomp(7061,[5,2],7)
++ (9) <152> decomp(7061,[5,2],9)
++ (10) <152> decomp(7061,[5,2],11)
++ (11) <152> decomp(7061,[5,2],13)
++ (12) <152> decomp(7061,[5,2],15)
++ (13) <152> decomp(7061,[5,2],17)
++ (14) <152> decomp(7061,[5,2],19)
++ (15) <152> decomp(7061,[5,2],21)
++ (16) <152> decomp(7061,[5,2],23)
++ (17) <150> decomp(307,[23,5,2],23)
-- (17) [307,23,5,2]
-- (16) [307,23,5,2]
-- (15) [307,23,5,2]
-- (14) [307,23,5,2]
-- (13) [307,23,5,2]
-- (12) [307,23,5,2]
-- (11) [307,23,5,2]
-- (10) [307,23,5,2]
-- (9) [307,23,5,2]
-- (8) [307,23,5,2]
-- (7) [307,23,5,2]
-- (6) [307,23,5,2]
-- (5) [307,23,5,2]
-- (4) [307,23,5,2]
-- (3) [307,23,5,2]
++ (3) <147> lists:reverse([307,23,5,2])
[2,5,23,307]
2>
1>帮助编号:decomp(70610)。
++(3)反编译(70610,[],2)
++(4)反编译(35305[2],2)
++(5)反编译(35305[2],3)
++(6)反编译(35305[2],5)
++(7)反编译(7061[5,2],5)
++(8)反编译(7061[5,2],7)
++(9)反编译(7061[5,2],9)
++(10)反编译(7061[5,2],11)
++(11)反编译(7061[5,2],13)
++(12)反编译(7061[5,2],15)
++(13)反编译(7061[5,2],17)
++(14)反编译(7061[5,2],19)
++(15)反编译(7061,[5,2],21)
++(16)反编译(7061[5,2],23)
++(17)反编译(307[23,5,2],23)
-- (17) [307,23,5,2]
-- (16) [307,23,5,2]
-- (15) [307,23,5,2]
-- (14) [307,23,5,2]
-- (13) [307,23,5,2]
-- (12) [307,23,5,2]
-- (11) [307,23,5,2]
-- (10) [307,23,5,2]
-- (9) [307,23,5,2]
-- (8) [307,23,5,2]
-- (7) [307,23,5,2]
-- (6) [307,23,5,2]
-- (5) [307,23,5,2]
-- (4) [307,23,5,2]
-- (3) [307,23,5,2]
++(3)列表:反向([307,23,5,2])
[2,5,23,307]
2>
乍看之下,我发现代码中有两件事不起作用:
除非您更详细地解释代码应该如何工作,否则我认为我无法提供更好的帮助。这里有一个实现示例。你不必关注
下一步\u可能是\u prime/2
。您可以使用simpleOld+2
。这只是优化
-module(factor).
-export([factor/1, make_wheels/0]).
factor(X) when is_integer(X), X > 0 ->
factor(X, 2, first_primes_steps()).
factor(X, X, _) -> [X];
factor(X, Prime, Wheel) when X rem Prime =:= 0 ->
[Prime|factor(X div Prime, Prime, Wheel)];
factor(X, Old, Wheel) when Old*Old < X ->
{MayBePrime, Wheel2} = next_may_be_prime(Old, Wheel),
factor(X, MayBePrime, Wheel2);
factor(X, _, _) -> [X].
%%% Prime candidates generator
next_may_be_prime(X, [Add|T]) ->
{X+Add, case T of [] -> wheel(); _ -> T end}.
first_primes_steps() -> [1,2,2,4,2].
wheel() ->
[4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,14,4,6,2,
10,2,6,6,4,2,4,6,2,10,2,4,2,12,10,2,4,2,4,6,2,6,4,6,6,6,2,6,
4,2,6,4,6,8,4,2,4,6,8,6,10,2,4,6,2,6,6,4,2,4,6,2,6,4,2,6,10,
2,10,2,4,2,4,6,8,4,2,4,12,2,6,4,2,6,4,6,12,2,4,2,4,8,6,4,6,
2,4,6,2,6,10,2,4,6,2,6,4,2,4,2,10,2,10,2,4,6,6,2,6,6,4,6,6,
2,6,4,2,6,4,6,8,4,2,6,4,8,6,4,6,2,4,6,8,6,4,2,10,2,6,4,2,4,
2,10,2,10,2,4,2,4,8,6,4,2,4,6,6,2,6,4,8,4,6,8,4,2,4,2,4,8,6,
4,6,6,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2,10,2,6,4,6,2,6,4,2,4,
6,6,8,4,2,6,10,8,4,2,4,2,4,8,10,6,2,4,8,6,6,4,2,4,6,2,6,4,6,
2,10,2,10,2,4,2,4,6,2,6,4,2,4,6,6,2,6,6,6,4,6,8,4,2,4,2,4,8,
6,4,8,4,6,2,6,6,4,2,4,6,8,4,2,4,2,10,2,10,2,4,2,4,6,2,10,2,
4,6,8,6,4,2,6,4,6,8,4,6,2,4,8,6,4,6,2,4,6,2,6,6,4,6,6,2,6,6,
4,2,10,2,10,2,4,2,4,6,2,6,4,2,10,6,2,6,4,2,6,4,6,8,4,2,4,2,
12,6,4,6,2,4,6,2,12,4,2,4,8,6,4,2,4,2,10,2,10,6,2,4,6,2,6,4,
2,4,6,6,2,6,4,2,10,6,8,6,4,2,4,8,6,4,6,2,4,6,2,6,6,6,4,6,2,
6,4,2,4,2,10,12,2,4,2,10,2,6,4,2,4,6,6,2,10,2,6,4,14,4,2,4,
2,4,8,6,4,6,2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,12,2,12].
%%% Auxiliary functions for making prime wheels
make_wheels() ->
%%%%%%%%%%%%%%%%
Primes = [2,3,5,7,11],
Next = 13,
%%%%%%%%%%%%%%%%
Period = lists:foldl(fun(X, A) -> X*A end, 1, Primes),
Max = Period + Next,
F = fun(X, A) -> array:set(X, false, A) end,
G = fun(X, A) -> lists:foldl(F, A, lists:seq(X, Max, X)) end,
Sieve = lists:foldl(G, array:new([{default, true}]), Primes),
{
diffs(Primes ++ [Next]),
diffs([ X || X <- lists:seq(Next, Max), array:get(X, Sieve)])
}.
diffs([H|T]) ->
diffs(H, T).
diffs(_, []) -> [];
diffs(A, [B|T]) -> [B-A|diffs(B, T)].
-模块(系数)。
-出口([系数/1,制造车轮/0])。
因子(X)为_整数(X),X>0->
因子(X,2,first_primes_steps())。
因子(X,X,ux)->[X];
当X rem Prime=:=0->
[Prime |因子(X div Prime,Prime,Wheel)];
旧*旧
{MayBePrime,Wheel2}=下一个可能是(旧的,Wheel),
因子(X,可能是素数,轮2);
因子(X,,-->[X]。
%%%素候选者生成器
下一个可能是素数(X,[Add | T])->
{X+Add,[]->wheel();u->T end}的案例T。
第一个素数步骤()->[1,2,2,4,2]。
轮子()->
[4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,14,4,6,2,
10,2,6,6,4,2,4,6,2,10,2,4,2,12,10,2,4,2,4,6,2,6,4,6,6,6,2,6,
4,2,6,4,6,8,4,2,4,6,8,6,10,2,4,6,2,6,6,4,2,4,6,2,6,4,2,6,10,
2,10,2,4,2,4,6,8,4,2,4,12,2,6,4,2,6,4,6,12,2,4,2,4,8,6,4,6,
2,4,6,2,6,10,2,4,6,2,6,4,2,4,2,10,2,10,2,4,6,6,2,6,6,4,6,6,
2,6,4,2,6,4,6,8,4,2,6,4,8,6,4,6,2,4,6,8,6,4,2,10,2,6,4,2,4,
2,10,2,10,2,4,2,4,8,6,4,2,4,6,6,2,6,4,8,4,6,8,4,2,4,2,4,8,6,
4,6,6,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2,10,2,6,4,6,2,6,4,2,4,
6,6,8,4,2,6,10,8,4,2,4,2,4,8,10,6,2,4,8,6,6,4,2,4,6,2,6,4,6,
2,10,2,10,2,4,2,4,6,2,6,4,2,4,6,6,2,6,6,6,4,6,8,4,2,4,2,4,8,
6,4,8,4,6,2,6,6,4,2,4,6,8,4,2,4,2,10,2,10,2,4,2,4,6,2,10,2,
4,6,8,6,4,2,6,4,6,8,4,6,2,4,8,6,4,6,2,4,6,2,6,6,4,6,6,2,6,6,
4,2,10,2,10,2,4,2,4,6,2,6,4,2,10,6,2,6,4,2,6,4,6,8,4,2,4,2,
12,6,4,6,2,4,6,2,12,4,2,4,8,6,4,2,4,2,10,2,10,6,2,4,6,2,6,4,
2,4,6,6,2,6,4,2,10,6,8,6,4,2,4,8,6,4,6,2,4,6,2,6,6,6,4,6,2,
6,4,2,4,2,10,12,2,4,2,10,2,6,4,2,4,6,6,2,10,2,6,4,14,4,2,4,
2,4,8,6,4,6,2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,12,2,12].
%%%制造主轮的辅助功能
制造车轮()->
%%%%%%%%%%%%%%%%
素数=[2,3,5,7,11],
下一个=13,
%%%%%%%%%%%%%%%%
周期=列表:foldl(乐趣(X,A)->X*A结束,1,素数),
最大值=周期+下一个,
F=fun(X,A)->array:set(X,false,A)end,
G=fun(X,A)->列表:foldl(F,A,列表:seq(X,Max,X))结束,
Sieve=list:foldl(G,数组:new([{default,true}]),Primes),
{
diff(Primes++[Next]),
差异([X | | X
差分(H,T)。
差异(u,[])->[];
微分(A[B | T])->[B-A |微分(B,T)]。
我想使用一个N数,并返回一个所有N的因子列表。我想做的是让每个数小于N,然后用N除以该数,循环生成它们。例如,如果我有3,我会得到(N-1)=2…3/2…不会除法,所以我将转到下一个数字。您可以在if
语句中进行递归。没有这样的限制。在if语句的子句体中,是的。在保护表达式中,不是。有这样的限制。与if
语句无关,所有保护都不能包含用户函数。相同的缺点train对于函数子句卫士和case语句子句卫士也是有效的。为什么最初要反转列表?列表反转是在分解求值结束时完成的,这只是因为当我执行此函数时,我希望得到从最小到最大排序的素因子。算法这是构建列表的常用方法,因为它避免了在每一步都创建一个新的副本;最后进行反向操作的成本比那些多个副本要低。
-module(factor).
-export([factor/1, make_wheels/0]).
factor(X) when is_integer(X), X > 0 ->
factor(X, 2, first_primes_steps()).
factor(X, X, _) -> [X];
factor(X, Prime, Wheel) when X rem Prime =:= 0 ->
[Prime|factor(X div Prime, Prime, Wheel)];
factor(X, Old, Wheel) when Old*Old < X ->
{MayBePrime, Wheel2} = next_may_be_prime(Old, Wheel),
factor(X, MayBePrime, Wheel2);
factor(X, _, _) -> [X].
%%% Prime candidates generator
next_may_be_prime(X, [Add|T]) ->
{X+Add, case T of [] -> wheel(); _ -> T end}.
first_primes_steps() -> [1,2,2,4,2].
wheel() ->
[4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,14,4,6,2,
10,2,6,6,4,2,4,6,2,10,2,4,2,12,10,2,4,2,4,6,2,6,4,6,6,6,2,6,
4,2,6,4,6,8,4,2,4,6,8,6,10,2,4,6,2,6,6,4,2,4,6,2,6,4,2,6,10,
2,10,2,4,2,4,6,8,4,2,4,12,2,6,4,2,6,4,6,12,2,4,2,4,8,6,4,6,
2,4,6,2,6,10,2,4,6,2,6,4,2,4,2,10,2,10,2,4,6,6,2,6,6,4,6,6,
2,6,4,2,6,4,6,8,4,2,6,4,8,6,4,6,2,4,6,8,6,4,2,10,2,6,4,2,4,
2,10,2,10,2,4,2,4,8,6,4,2,4,6,6,2,6,4,8,4,6,8,4,2,4,2,4,8,6,
4,6,6,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2,10,2,6,4,6,2,6,4,2,4,
6,6,8,4,2,6,10,8,4,2,4,2,4,8,10,6,2,4,8,6,6,4,2,4,6,2,6,4,6,
2,10,2,10,2,4,2,4,6,2,6,4,2,4,6,6,2,6,6,6,4,6,8,4,2,4,2,4,8,
6,4,8,4,6,2,6,6,4,2,4,6,8,4,2,4,2,10,2,10,2,4,2,4,6,2,10,2,
4,6,8,6,4,2,6,4,6,8,4,6,2,4,8,6,4,6,2,4,6,2,6,6,4,6,6,2,6,6,
4,2,10,2,10,2,4,2,4,6,2,6,4,2,10,6,2,6,4,2,6,4,6,8,4,2,4,2,
12,6,4,6,2,4,6,2,12,4,2,4,8,6,4,2,4,2,10,2,10,6,2,4,6,2,6,4,
2,4,6,6,2,6,4,2,10,6,8,6,4,2,4,8,6,4,6,2,4,6,2,6,6,6,4,6,2,
6,4,2,4,2,10,12,2,4,2,10,2,6,4,2,4,6,6,2,10,2,6,4,14,4,2,4,
2,4,8,6,4,6,2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,12,2,12].
%%% Auxiliary functions for making prime wheels
make_wheels() ->
%%%%%%%%%%%%%%%%
Primes = [2,3,5,7,11],
Next = 13,
%%%%%%%%%%%%%%%%
Period = lists:foldl(fun(X, A) -> X*A end, 1, Primes),
Max = Period + Next,
F = fun(X, A) -> array:set(X, false, A) end,
G = fun(X, A) -> lists:foldl(F, A, lists:seq(X, Max, X)) end,
Sieve = lists:foldl(G, array:new([{default, true}]), Primes),
{
diffs(Primes ++ [Next]),
diffs([ X || X <- lists:seq(Next, Max), array:get(X, Sieve)])
}.
diffs([H|T]) ->
diffs(H, T).
diffs(_, []) -> [];
diffs(A, [B|T]) -> [B-A|diffs(B, T)].