因爲我不確定其他答案中的建議,下面是我對你的問題的看法。
首先,不要定義自己的append/3
和length/2
,append/3
是現在Prolog的民間傳說,你可以在textbooks 30 years old找到它。並且length/2
真的很難獨立完成,請使用內置的。
現在:採取在列表L
的前第一N
元素,你可以說:
length(Front, N),
append(Front, _, L)
你創建你所需要的長度的列表,然後使用append/3
拆斷這個前從你有的名單。
考慮到這一點,就足以界定謂詞sliding_window/3
:
sliding_window(L, N, [L]) :-
length(L, N).
sliding_window(L, N, [W|Ws]) :-
W = [_|_], % W should be at least one long
length(W, N),
append(W, _, L),
L = [_|L0],
sliding_window(L0, N, Ws).
這類作品,但它會爲您提供所有有用的答案後循環:
?- sliding_window([a,b], N, Ws).
N = 2,
Ws = [[a, b]] ;
N = 1,
Ws = [[a], [b]] ;
% loops
它因爲有相同的小片段:
length(Front, N),
append(Front, _, L)
With length/2
,你繼續生成增加長度的列表;一旦Front
比L
更長,append/3
失敗,length/2
會產生一個更長的列表,等等。
其中一種方法是使用between/3
約束前端的長度。如果你把它放在自己的斷言:
front_n(L, N, F) :-
length(L, Max),
between(1, Max, N),
length(F, N),
append(F, _, L).
有了這個:
sliding_window(L, N, [L]) :-
length(L, N).
sliding_window(L, N, [W|Ws]) :-
front_n(L, N, W),
L = [_|L0],
sliding_window(L0, N, Ws).
而現在它終於作品:
?- sliding_window([a,b,c,d], 3, Ws).
Ws = [[a, b, c], [b, c, d]] ;
false.
?- sliding_window([a,b,c], N, Ws).
N = 3,
Ws = [[a, b, c]] ;
N = 1,
Ws = [[a], [b], [c]] ;
N = 2,
Ws = [[a, b], [b, c]] ;
false.
練習:擺脫無害的,但不必要的選擇點。
我感覺這是關於滑動窗口,而不是關於給定長度的所有子序列。這僅僅是通過閱讀這個例子,我不認爲這是在問題中明確定義的。 – 2016-11-29 12:50:31