Prolog中具有k个元素的列表的所有子集

Prolog中具有k个元素的列表的所有子集,prolog,Prolog,请帮我解决这个问题: 子集(N[1,2,3],L) 如果N=2,我希望结果是: [1,2] [2,1] [1,3] [3,1] [2,3] [3,2] (以任何顺序)好吧,你的基本情况很简单: subset(0,Lst,[]). 如果N>0,那么对于如何处理Lst的第一个元素,您有两个选择: 您可以忽略它,并在Lst的剩余部分中查找您的子集 您可以将其包含在子集中,将其添加到Lst剩余部分的较小子集中 你可能认为你必须担心Lst太短(或者N太大:同样的事情),但是如果你已经正确地编码了上面的内

请帮我解决这个问题:

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

如果N=2,我希望结果是:

[1,2]

[2,1]

[1,3]

[3,1]

[2,3]

[3,2]


(以任何顺序)

好吧,你的基本情况很简单:

subset(0,Lst,[]).
如果N>0,那么对于如何处理Lst的第一个元素,您有两个选择:

  • 您可以忽略它,并在Lst的剩余部分中查找您的子集
  • 您可以将其包含在子集中,将其添加到Lst剩余部分的较小子集中
  • 你可能认为你必须担心Lst太短(或者N太大:同样的事情),但是如果你已经正确地编码了上面的内容,你就应该注意它

    这就足够让你开始了。

    我重写了这个解决方案:(基于:)

    结果(在SWI Prolog中测试):


    如果是家庭作业,请标记为suchselect/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];我的解决方案:
    子集(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];您的解决方案的结果看起来与您最初所说的一样,除了反向的重复项。如果您仍然需要它们,您将需要一个规则来生成与您现在生成的相反的结果。但它不起作用。不确定你所说的“不起作用”是什么意思,但即使它起作用了,它也不能解决N>2的问题。你需要的不是总是取出列表中的第一个元素,而是取出一个任意元素,这样所有的排列都是可能的。
    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).
    
    ?- 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.