问题描述
我目前的目标是编写 Erlang 代码来计算 N 个元素的列表,其中每个元素都是它的索引"的阶乘(因此,对于 N = 10,我想得到 [1!, 2!,3!, ..., 10!]).更重要的是,我希望每个元素都在一个单独的过程中进行计算(我知道它的效率很低,但我希望我可以实现它,并在以后将其效率与其他方法进行比较).
My objective at the moment is to write Erlang code calculating a list of N elements, where each element is a factorial of it's "index" (so, for N = 10 I would like to get [1!, 2!, 3!, ..., 10!]). What's more, I would like every element to be calculated in a seperate process (I know it is simply inefficient, but I am expected to implement it and compare its efficiency with other methods later).
在我的代码中,我想使用一个函数作为给定 N 的循环",对于 N、N-1、N-2... 产生一个计算阶乘(N)并将结果发送到一些收集"功能,它将接收到的结果打包到一个列表中.我知道我的概念可能过于复杂,所以希望代码能解释得更多:
In my code, I wanted to use one function as a "loop" over given N, that for N, N-1, N-2... spawns a process which calculates factorial(N) and sends the result to some "collecting" function, which packs received results into a list. I know my concept is probably overcomplicated, so hopefully the code will explain a bit more:
messageFactorial(N, listPID) ->
listPID ! factorial(N). %% send calculated factorial to "collector".
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nProcessesFactorialList(-1) ->
ok;
nProcessesFactorialList(N) ->
spawn(pFactorial, messageFactorial, [N, listPID]), %%for each N spawn...
nProcessesFactorialList(N-1).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
listPrepare(List) -> %% "collector", for the last factorial returns
receive %% a list of factorials (1! = 1).
1 -> List;
X ->
listPrepare([X | List])
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
startProcessesFactorialList(N) ->
register(listPID, spawn(pFactorial, listPrepare, [[]])),
nProcessesFactorialList(N).
我想它会起作用,我的意思是 listPrepare 最终会返回一个阶乘列表.但问题是,我不知道如何得到那个列表,如何得到它返回的内容?至于现在我的代码返回正常,因为这是 nProcessesFactorialList 在完成时返回的内容.我想最后将 listPrepare 的结果列表从 listPrepare 发送到 nProcessesFactorialList,但它也需要是一个注册进程,我不知道如何从中恢复该列表.
I guess it shall work, by which I mean that listPrepare finally returns a list of factorials. But the problem is, I do not know how to get that list, how to get what it returned? As for now my code returns ok, as this is what nProcessesFactorialList returns at its finish. I thought about sending the List of results from listPrepare to nProcessesFactorialList in the end, but then it would also need to be a registered process, from which I wouldn't know how to recover that list.
那么基本上,如何从运行 listPrepare(这是我的阶乘列表)的注册进程中获取结果?如果我的代码根本不正确,我会询问如何改进它的建议.提前致谢.
So basically, how to get the result from a registered process running listPrepare (which is my list of factorials)? If my code is not right at all, I would ask for a suggestion of how to get it better. Thanks in advance.
推荐答案
我处理这类任务的方式是
My way how to do this sort of tasks is
-module(par_fact).
-export([calc/1]).
fact(X) -> fact(X, 1).
fact(0, R) -> R;
fact(X, R) when X > 0 -> fact(X-1, R*X).
calc(N) ->
Self = self(),
Pids = [ spawn_link(fun() -> Self ! {self(), {X, fact(X)}} end)
|| X <- lists:seq(1, N) ],
[ receive {Pid, R} -> R end || Pid <- Pids ].
和结果:
> par_fact:calc(25).
[{1,1},
{2,2},
{3,6},
{4,24},
{5,120},
{6,720},
{7,5040},
{8,40320},
{9,362880},
{10,3628800},
{11,39916800},
{12,479001600},
{13,6227020800},
{14,87178291200},
{15,1307674368000},
{16,20922789888000},
{17,355687428096000},
{18,6402373705728000},
{19,121645100408832000},
{20,2432902008176640000},
{21,51090942171709440000},
{22,1124000727777607680000},
{23,25852016738884976640000},
{24,620448401733239439360000},
{25,15511210043330985984000000}]
这篇关于在 Erlang 中获取衍生函数的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!