我需要一个谓词来返回输入列表的所有组合的列表,并且列表结果的大小在第二个参数中,谓词就是这样
permutInListN( +inputList, +lengthListResult, -ListResult),
示例:
permutInListN([1,2,3],2,L).
? L=[1,2].
? L=[2,1].
? L=[1,3].
? L=[3,1].
? L=[2,3].
? L=[3,2].
列表[1,2,3]
中L
的组合,其长度为2
。
没有重复可能使用抵消。
这是我的代码,但是根本不起作用,没有生成所有解决方案
permutInListN(_, 0, []).
permutInListN([X|Xs], N, [X|Ys]) :- N1 is N-1, permutInListN(Xs,N1,Ys).
permutInListN([_|Xs], N, Y) :- N>0, permutInListN(Xs,N,Y).
?permutInListN([1,2,3],2,L).
L = [1, 2]
L = [1, 3]
L = [2, 3]
提前谢谢。
答案 0 :(得分:4)
您想要的是组合和排列。
对于组合:
comb(0,_,[]).
comb(N,[X|T],[X|Comb]) :-
N>0,
N1 is N-1,
comb(N1,T,Comb).
comb(N,[_|T],Comb) :-
N>0,
comb(N,T,Comb).
示例:
?- comb(2,[1,2,3],List).
List = [1, 2] ;
List = [1, 3] ;
List = [2, 3] ;
false.
对于置换,只需在库列表中使用SWI-Prolog permutation/2
:- use_module(library(lists)).
?- permutation([1,2],R).
R = [1, 2] ;
R = [2, 1] ;
false.
将它们放在一起
comb_perm(N,List,Result) :-
comb(N,List,Comb),
permutation(Comb,Result).
与您的查询
?- comb_perm(2,[1,2,3],R).
R = [1, 2] ;
R = [2, 1] ;
R = [1, 3] ;
R = [3, 1] ;
R = [2, 3] ;
R = [3, 2] ;
false.
为您的谓词修改
permutInListN(List,N,Result) :-
comb(N,List,Comb),
permutation(Comb,Result).
示例
?- permutInListN([1,2,3],2,R).
R = [1, 2] ;
R = [2, 1] ;
R = [1, 3] ;
R = [3, 1] ;
R = [2, 3] ;
R = [3, 2] ;
false.
答案 1 :(得分:1)
您的permutInListN/3
谓词基本上从给定列表中以有序的方式获取N
个元素,但所选择元素的顺序与原始元素相同订单。
因此,我们可以通过查找所选元素的所有排列来对该列表进行后处理,例如:
permutInListN(L, N, R) :-
takeN(L, N, S),
permutation(S, R).
takeN/3
几乎等于您定义的谓词:
takeN(_, 0, []).
takeN([X|Xs], N, [X|Ys]) :-
N > 0,
N1 is N-1,
takeN(Xs,N1,Ys).
takeN([_|Xs], N, Y) :-
N > 0,
takeN(Xs,N,Y).
permutation/3
[swi-doc]是lists
library [swi-doc]的谓词。
select/3
s 我们也可以使用select/3
predicate [swi-doc] N
次来解决问题。 select(X, L, R)
从列表中获取元素X
,而R
是列表,没有该元素。因此,我们可以递归地传递列表,每次删除一个元素,直到删除N
个元素,例如:
permutInListN(_, 0, []).
permutInListN(L, N, [X|T]) :-
N > 0,
N1 is N-1,
select(X, L, R),
permutInListN(R, N1, T).