當你必須一個一個「計數」的東西,考慮使用succ/2
。它具有很好的屬性,它可以同時工作,並且在與succ(X, 0)
通話時失敗。
因此,首先,做「累積重複」謂詞:
cum_dup([], _, []).
cum_dup([X|Xs], N, Ys) :-
repeat_n(X, N, Ys, Back),
succ(N, N1),
cum_dup(Xs, N1, Back).
這使用謂詞repeat_n/4
,這需要一個元件,一個非負整數,並且重複的元素。它在列表的後面留下一個「洞」,您可以使用cum_dup/3
填充結果的其餘部分。這裏是一個直觀的實現的repeat_n/4
:
repeat_n(_, 0, L, L).
repeat_n(X, N, [X|Xs], Rest) :-
succ(N0, N),
repeat_n(X, N0, Xs, Rest).
這已經給你所需要的結果:
?- cum_dup([a,b,c,d], 2, R).
R = [a, a, b, b, b, c, c, c, c, d, d, d, d, d] ;
false
它留下一個無害的選擇點之後。有太多的方法可以讓repeat_n/4
不留下不必要的選用要點:
- 使用CLP(FD)
- 使用切割
- 使用條件(IF-THEN-ELSE)
- 使用的結構,而不是一個整數的
只是一個例子:
repeat_n(X, N, L, Back) :-
length(Ns, N),
repeat_n_(Ns, X, L, Back).
repeat_n_([], _, L, L).
repeat_n_([_|Ns], X, [X|Xs], L) :-
repeat_n_(Ns, X, Xs, L).
這裏,您不用一個整數來計算,而是(ab)使用該長度的列表。
我想你可以自己想一想,如果你真的需要問另一個問題。
儘管我想給你的答案:考慮添加一個謂詞n_of(N,Element,List),它會給你一個N次元素列表,如下所示: '? - n_of(2,a,L )' 'L = [a,a]' –
@SpinyNorman對於差異列表,如果'n_of'有4個參數而不是3個,那將會更好。否則,'n_of/3'就像'length(L,N),maplist(=(Element),L)'一樣簡單。 – 2016-11-25 02:40:40