因子数(Erlang)

时间:2015-05-07 16:10:04

标签: function recursion erlang

我希望根据Erlang中的Head或Middle递归对数字进行分解。该函数称为fact,取1个参数,fact / 1。结果将返回作为数字因子的数字列表。

24返回以下内容:[1,2,3,4,6,8,12,24]

有没有人有任何想法我会怎么做?

3 个答案:

答案 0 :(得分:2)

我建议你这个解决方案。我首先搜索素因子中的分解,然后构建除数列表。我认为平均来说应该更有效率。

divlist(N) -> automult([1|decomp(N)]).

decomp(N) when is_integer(N), (N > 0) -> 
    lists:reverse(decomp(N,[],2)).

decomp(N,R,I) when I*I > N -> [N|R];
decomp(N,R,I) when (N rem I) =:= 0 -> decomp(N div I,[I|R],I);
decomp(N,R,2) -> decomp(N,R,3);
decomp(N,R,I) -> decomp(N,R,I+2).

automult(L=[H]) when is_number(H)-> L;
automult([H|Q]) when is_number(H)->
    L1 = automult(Q),
    L2 = [H*X || X <- L1],
    lists:usort([H|L1]++L2).

@ Zoukaye和@P_A和我提出的解决方案给出了相同的结果,但是他们的解决方案都具有O(n)的复杂性。我的建议评估起来比较复杂,因为它分为两部分。搜索或素数分解主要由0(log(n)),第二部分取决于第一部分的结果,有趣的是,它不是两个部分的最坏情况:

  • 如果一个数字有很多素数因子,那么它们的搜索速度很快,所有分频器的构成都需要更长的时间。
  • 如果一个数字具有很少(1)素因子,则搜索需要更长时间,但组成很短。

最后一句话,@ Zoukaye使用整数的中间列表。如果你打算将它用于looooong整数,那么这是一个坏主意,因为只有构建这个列表才会因内存不足而崩溃。

我做了一个性能测试,比较了我创建一个小于Max的N个随机数列表的解决方案,评估每个解决方案的整个执行时间,验证它们是等效的还是返回时间。结果是

数量少于10 000的10000次测试:

我的:63ms,P_A:788ms,Zoukaye:1383ms

10 000次测试,数量少于10万:

我的:80ms,P_A:9240ms,Zoukaye:13594ms

数量少于1000 000的10000次测试:

我的:105ms,P_A:101001ms,Zoukaye:137145ms

以下是我使用的代码:

-module (test).

-compile((export_all)).


test(Nbtest,Max) ->
    random:seed(erlang:now()),
    L = [random:uniform(Max) || _ <- lists:seq(1,Nbtest)],
    F1 = fun() -> [{X,divlist(X)} || X <- L] end,
    F2 = fun() -> [{X,fact_comp(X)} || X <- L] end,
    F3 = fun() -> [{X,fact_rec(X)} || X <- L] end,
    {T1,R} = timer:tc(F1),
    {T2,R} = timer:tc(F2),
    {T3,R} = timer:tc(F3),
    {T1,T2,T3}.


% Method1
divlist(N) -> automult([1|decomp(N)]).

decomp(N) when is_integer(N), (N > 0) -> 
    lists:reverse(decomp(N,[],2)).

decomp(N,R,I) when I*I > N -> [N|R];
decomp(N,R,I) when (N rem I) =:= 0 -> decomp(N div I,[I|R],I);
decomp(N,R,2) -> decomp(N,R,3);
decomp(N,R,I) -> decomp(N,R,I+2).

automult(L=[H]) when is_number(H)-> L;
automult([H|Q]) when is_number(H)->
    L1 = automult(Q),
    L2 = [H*X || X <- L1],
    lists:usort([H|L1]++L2).

% Method 2
fact_comp(N) ->
    if N > 0  ->
         [ V || V <- lists:seq(1, N div 2), N rem V =:= 0 ] ++ [ N ];
       N < 0 -> 
         Na = 0 - N,
         [ V || V <- lists:seq(1, Na div 2), Na rem V =:= 0 ] ++ [ Na ];
       N =:= 0 -> []
    end.


% Method 3
fact_rec(N) ->
    fact_rec(N, 1, []).

fact_rec(N, I, Acc) when I =< trunc(N/2) ->
    case N rem I of
        0 -> fact_rec(N, I+1, [I | Acc]);
        _ -> fact_rec(N, I+1, Acc)
    end;
fact_rec(N, _I, Acc) -> lists:reverse(Acc) ++ [N].

答案 1 :(得分:0)

这样的东西?

Object.first.created_at

答案 2 :(得分:0)

使用列表理解

fact_comp(N) ->
    if N > 0  ->
         [ V || V <- lists:seq(1, N div 2), N rem V =:= 0 ] ++ [ N ];
       N < 0 -> 
         Na = 0 - N,
         [ V || V <- lists:seq(1, Na div 2), Na rem V =:= 0 ] ++ [ Na ];
       N =:= 0 -> []
    end.