注意:这是我以前的排列question的“续集”问题。
我想在Erlang中生成列表的所有排列,但我想在将它们添加到堆栈或存储在任何地方之前过滤掉一些排列。
我会根据一些自定义的临时规则过滤掉排列(让我们称之为“过滤器”)。
换句话说,我想生成一个大型列表的排列列表(50-300个元素),但我想在此过程中抛出大部分生成的排列(我知道全部数字)排列是N!)。
steenslag在Ruby中给了我一个很好的solution:
res = [1,2,3,4].permutation(3).reject do |perm|
perm.first.even? #Filter: if this line is true, the perm will be rejected
end
如何在Erlang中编写类似内容?
(我的Filter函数已经用Erlang编写了,所以我想做一些代码重用)。
顺便说一句,所需的Erlang解决方案能否“内在并行”?
答案 0 :(得分:2)
您可以在构建后立即过滤排列。
只是一个例子,这个run()返回以偶数开头的[1,2,3,4]的所有排列。函数'check'(过滤结果)1)检查它是否是完全排列(结果长度==源列表长度),然后2)检查过滤条件(在我的情况下 - 第一个数字是偶数)。
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. .
答案 1 :(得分: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).
它使用空列表作为必须丢弃的列表的占位符。如果这是不可接受的,您可以将实现更改为不使用list compreension。
pred / 1函数只是一个用作谓词的示例函数。
希望这有帮助。