基本上,我需要创建表单子列表(S,M,N,L)的谓词,其中S是由索引M和索引N之间的L元素组成的新列表,包括在内。
这是我得到的地方:
sublist([],_,_,[]).
sublist([],M,N,_) :- (M > N).
sublist(S,M,N,L) :- sublist2(S,M,N,L,-1).
sublist2([H|T],St,En,[H2|T2],Idx) :-
(Idx2 is Idx + 1,
St =< Idx2,
En >= Idx2,
H = H2,
sublist2(T,St,En,T2,Idx2);
Idx2 is Idx + 1,
sublist2(T,St,En,T2,Idx2)).
与我所有的prolog问题一样,我觉得我的方式比它应该更复杂。我已经确定了基本情况,但其他任何评估都是错误的。对这个问题的任何建议,以及prolog的一般方法?我在很大程度上理解这种语言,但我似乎无法看到简单的解决方案。
答案 0 :(得分:1)
简单的解决方案遵循简单的前景。对于列表,它是递归。递归编程很简单 - 想象一下你已经拥有了你的函数,遵循给定的接口/要求,所以你可以随时使用它(但更好的是,在减少的情况下)。
sublist(S,M,N,[_A|B]):- M>0, M<N, sublist(S,M-1,N-1,B).
将其视为陈述一个子列表法则:较短列表中的子列表从减少的索引开始。
sublist(S,M,N,[A|B]):- 0 is M, M<N, N2 is N-1, S=[A|D], sublist(D,0,N2,B).
和
sublist([],0,0,_).
它在第二个索引中是独占的。调整它。 :)
答案 1 :(得分:1)
有可能以类似于更传统语言的方式处理索引:
sublist(L, M, N, S) :-
findall(E, (nth1(I, L, E), I >= M, I =< N), S).
或等效
sublist(L, M, N, S) :-
findall(E, (between(M, N, I), nth1(I, L, E)), S).
nth1 / 3用于从1开始索引,否则nth0 / 3允许C风格 - 从0开始。我已将子列表作为最后一个参数。 Prolog中的常见约定是在输入后放置输出参数。
这是一个(繁琐的)递归定义
sublist(L,M,N,S) :- sublist2(1,L,M,N,S).
sublist2(_,[],_,_,[]).
sublist2(I,[X|Xs],M,N,[X|Ys]) :-
between(M,N,I),
J is I + 1,
!, sublist2(J,Xs,M,N,Ys).
sublist2(I,[_|Xs],M,N,Ys) :-
J is I + 1,
sublist2(J,Xs,M,N,Ys).