我想生成一组P(S)
的powerset S
。我希望P(S)
只有一个等于一定大小的子集。
例如,如果我们有S = [1,2,3,4]
,则limited_powerset(S,3)
将为[[1,2,3],[2,3,4],[1,3,4],[1,2,4]].
Hynek Pichi Vychodil提供了Erlang中一般powerset生成的一个很好的例子(谢谢!):
generate([]) -> [[]];
generate([H|T]) -> PT = generate(T),
generate(H, PT, PT).
generate(_, [], Acc) -> Acc;
generate(X, [H|T], Acc) -> generate(X, T, [[X|H]|Acc]).
如何修改它以仅包含特定大小的子集?引入Limit变量并将最后一行更改为
case length([X|H]) < Limit of
true ->
ps(X, T, Acc, Limit);
false ->
ps(X, T, [[X|H]|Acc],Limit)
end.
无济于事。
P.S。我想子集的数量将小于N!,但我怎样才能准确计算它呢?
答案 0 :(得分:3)
这将做你想要的:
limited_powerset(L, N) ->
{_, Acc} = generate(L, N),
Acc.
generate([], _) ->
{[[]], []};
generate([H|T], N) ->
{PT, Acc} = generate(T, N),
generate(H, PT, PT, Acc, N).
generate(_, [], PT, Acc, _) ->
{PT, Acc};
generate(X, [H|T], PT, Acc, N) when length(H)=/=N-1 ->
generate(X, T, [[X|H]|PT], Acc, N);
generate(X, [H|T], PT, Acc, N) ->
generate(X, T, [[X|H]|PT], [[X|H]|Acc], N).
这不是微不足道的。它让我难过了一会儿。诀窍是你需要在整个算法中维护完整的powerset累加器,并为有限集创建第二个累加器。