Recursion 使用Erlang生成自定义排列

Recursion 使用Erlang生成自定义排列,recursion,erlang,stack,permutation,Recursion,Erlang,Stack,Permutation,注:这是我之前排列的“续集”问题 我想在Erlang中生成列表的所有排列,但我想在将它们添加到堆栈或存储到任何位置之前过滤掉一些排列 我将根据一些定制的特殊规则过滤掉这些排列(我们称之为“过滤器”) 换句话说,我想生成一个大列表(50-300个元素)的置换列表,但我想在这个过程中丢弃大部分生成的置换(我知道置换的总数是N!) 给了我一个很好的Ruby: 如何在Erlang中编写类似的内容 (我已经用Erlang编写了过滤器函数,所以我想进行一些代码重用) 顺便问一下,所需的Erlang解决方案是

注:这是我之前排列的“续集”问题

我想在Erlang中生成列表的所有排列,但我想在将它们添加到堆栈或存储到任何位置之前过滤掉一些排列

我将根据一些定制的特殊规则过滤掉这些排列(我们称之为“过滤器”)

换句话说,我想生成一个大列表(50-300个元素)的置换列表,但我想在这个过程中丢弃大部分生成的置换(我知道置换的总数是N!)

给了我一个很好的Ruby:

如何在Erlang中编写类似的内容

(我已经用Erlang编写了过滤器函数,所以我想进行一些代码重用)


顺便问一下,所需的Erlang解决方案是否“本质上是并行的”?

我为这个问题做了一个可能的实现:

-module(perm).

-export([pred_perms/2, pred/1]).

pred(L = [H | _T]) when H > 1 ->
    L;
pred(_L) ->
    [].

do_pred_perms([], _Pred) -> 
    [[]];
do_pred_perms(L, Pred)  -> 
    [Pred([H|T]) || H <- L, T <- do_pred_perms(L--[H], Pred)].

pred_perms(List, Pred) ->
    Res = do_pred_perms(List, Pred),
    lists:filter(fun(E) -> E =/= [] end, Res).
-模块(perm)。
-导出([pred_perms/2,pred/1])。
当H>1->
L
pred(_L)->
[].
是否进行预处理([],\u pred)->
[[]];
做预处理(L,预处理)->
[Pred([H | T])| he=/=[]end,Res)。
它使用空列表作为必须放弃的列表的占位符。如果这不可接受,您可以将实现更改为不使用列表压缩

pred/1函数只是一个用作谓词的示例函数


希望这能有所帮助。

您可以在排列构造完成后立即对其进行筛选

举个例子,这个run()返回以偶数开头的[1,2,3,4]的所有排列。函数“check”(过滤结果)1)检查它是否是完全排列(结果长度==源列表长度),然后2)检查过滤条件(在我的例子中,第一个数字是偶数)

run()->
perm([1,2,3,4],4)。
perm([],417;)->
[[]];
perm(L,N)->[H | T]| H trunc(H/2)=H/2。

注意:这个实现不是“本质上的并行”。亲爱的Isac,谢谢你的回答。我先做L=list:seq(1,10),然后做F=fun perm:pred/2,然后做perm:pred_perms(L,F)。结果是**异常错误:perm:pred/2在函数perm:'-do_-pred_-perms/2-lc$^1/1-1-'/5在从perm调用时使用一个参数调用:'-do_-pred_-perms/2-lc$^0/1-0-'/3在从perm:pred_-perms/2调用时使用。我做错了什么?pred函数只接收到一个参数。将代码更改为:F=fun perm:pred/1。它应该可以工作。
-module(perm).

-export([pred_perms/2, pred/1]).

pred(L = [H | _T]) when H > 1 ->
    L;
pred(_L) ->
    [].

do_pred_perms([], _Pred) -> 
    [[]];
do_pred_perms(L, Pred)  -> 
    [Pred([H|T]) || H <- L, T <- do_pred_perms(L--[H], Pred)].

pred_perms(List, Pred) ->
    Res = do_pred_perms(List, Pred),
    lists:filter(fun(E) -> E =/= [] end, Res).
run() ->
    perm([1,2,3,4],4).

perm([],_) ->
    [[]];
perm(L,N) -> [[H|T] || H <- L, T <- perm(L--[H],N), check( [H|T] ,N) ].

check(L,N) when length(L) < N -> true;
check([H|_],_) -> trunc(H/2) == H/2. .