2013-07-01 178 views
4

我想寫一個Prolog的謂詞(SWI)會從列表中選擇N個元素,像這樣:選擇N個元素

selectn+ N? elems的?列表1?列表2)爲真時列表1,所有elems的去除,導致列表2

selectn(N,Lps,L1s,[]) :- length(L1s,L), N >= L, permutation(L1s,Lps). 
selectn(0,[],L1s,Lps) :- permutation(L1s,Lps). 
selectn(N,[E|Es],L1s,L2s) :- 
    select(E,L1s,L0s), 
    N0 is N-1, 
    selectn(N0,Es,L0s,L2s). 

我的問題是,在某些情況下,我得到重複的結果,我不知道如何避免它們:

?- findall(L,selectn(2,Es,[a,b,c],L),Ls),length(Ls,Solutions). 
Ls = [[c], [b], [c], [a], [b], [a]], 
Solutions = 6. 

這不是功課,但如果你想幫助我,如果是的話,我也會很高興。

回答

4

這可能會回答你的問題(雖然我不明白你的第一句話selectn/4,置換已經被 '套' 做選擇/ 3)

selectn(0, [], Rest, Rest). 
selectn(N, [A|B], C, Rest) :- 
    append(H, [A|T], C), 
    M is N-1, 
    selectn(M, B, T, S), 
    append(H, S, Rest). 

產量

?- findall(L,selectn(2,Es,[a,b,c],L),Ls),length(Ls,Solutions). 
Ls = [[c], [b], [a]], 
Solutions = 3. 
+0

謝謝爲您的回覆@CapelliC!它對我有很大的幫助。然而,在你的代碼中,排列並不是按照你所說的'selectn/4'完成的,當查詢'selectn(3,[c,a,b],[a,b,c, d],[d])。'或'selectn(0,[a,b],[b,a])。',當然是由於重複不被認爲是答案。 –

相關問題