【问题标题】:All subset of list with k elements in PrologProlog中具有k个元素的列表的所有子集
【发布时间】:2014-02-03 22:27:09
【问题描述】:

请帮我解决这个问题:

子集(N,[1,2,3],L)。

如果 N=2,我想要的结果是:

[1,2];

[2,1];

[1,3];

[3,1];

[2,3];

[3,2];

(以任何顺序)

【问题讨论】:

  • 如果是作业请标记为这样
  • select/3 内置可以帮你解决这个小问题
  • 请不要只发布您的作业,而是要付出一些努力。你试过什么?
  • 我的解决方案:
    子集(0,,[])。
    子集(N, [X | T], [X | R]) :- N > 0, N1 是 N - 1, 子集(N1, T, R)。
    子集(N,[
    | T],R):- N > 0,子集(N,T,R)。
    结果是:
    [1,2];[1,3];[2,3];

标签: prolog


【解决方案1】:

我重写了这个解决方案:(基于:Permuted combinations of the elements of a list - Prolog

subset(N, InList, Out) :-
    splitSet(InList,_,SubList),
    permutation(SubList,Out),
    length(Out, N).

splitSet([ ],[ ],[ ]).
splitSet([H|T],[H|L],R) :-
    splitSet(T,L,R).
splitSet([H|T],L,[H|R]) :-
    splitSet(T,L,R).

结果(在 SWI-Prolog 中测试):

?- subset(2,[1,2,3],R).
R = [2, 3] ;
R = [3, 2] ;
R = [1, 3] ;
R = [3, 1] ;
R = [1, 2] ;
R = [2, 1] ;
false.

【讨论】:

    【解决方案2】:

    好吧,你的基本情况是微不足道的:

    subset(0,Lst,[]).
    

    如果 N>0,对于如何处理 Lst 的第一个元素,您有 2 个选择:

    1. 您可以忽略它,并在 Lst 的剩余部分中查找您的子集
    2. 您可以将其包含在您的子集中,将其添加到您获得的 Lst 剩余部分的 1-smaller 子集中。

    您可能认为您必须担心 Lst 太短(或 N 太大:同样的事情),但如果您已正确编码上述内容,则应该为您处理。

    希望这足以让您入门。

    【讨论】:

    • 我的解决方案:
      子集(0,,[])。
      子集(N, [X | T], [X | R]) :- N > 0, N1 为 N - 1, 子集(N1, T, R)。
      子集(N,[
      | T],R):-N> 0,子集(N,T,R)。
      结果是:
      [1,2];[1,3];[2,3];
    • 您的解决方案的结果看起来就像您最初所说的那样,除了反向重复。如果您仍然需要它们,您将需要一个生成与现在生成的相反的规则。
    • 我尝试使用 SWI-Prolog 内置谓词反向来反转我的列表。但它不起作用。
    • 不确定你所说的“不起作用”是什么意思,但即使它起作用了,它也不能解决 N>2 的问题。您需要的不是总是取出列表的第一个元素,而是需要取出任意元素,以便所有排列都是可能的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2018-12-08
    • 1970-01-01
    • 2019-08-16
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多