所以我校园的教授要求我们解决这个问题,但是有点困难,我现在试了2天。无论如何它是:
我给出了一个例如[a,b,c,d,w,n,i,c,k,a,b,c,d,w]
的列表,在这个列表中我必须找出是否有"怀疑"子表。子列表被视为"怀疑"如果
1)相同的子列表在开头和结尾,
2)它包含" w",
3)它的长度为5。
我给出的清单有一个"怀疑"子列表。
如果存在可疑子列表,则程序必须返回子列表,或者如果没有,则必须返回[o,k]
。
欢迎任何想法,非常感谢! (对不起,如果我发布了错误的信息)
修改
所以在得到一些帮助之后是asnwer:
checkMessage1(L,SL):-
suspiciousMessage1(L,SL).
checkMessage1(L,[o,k]):-
not(suspiciousMessage1(L,SL)).
suspiciousMessage1(L,SL):-
append(SL,Last,L),
append(_,SL,Last),
length(SL,5),
member(w,SL).
答案 0 :(得分:2)
这是使用DCG的一个很好的例子:
list_suspect(Xs, Ys) :-
length(Ys, 5),
phrase(( seq(Ys), ..., seq(Ys) ), Xs),
phrase((...,"w",...), Ys).
... --> [] | [_], ... .
seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).
以下是使用append/3
的版本:
list_suspect(Xs, Ys) :-
Ys = [_,_,_,_,_],
append(Ys,Is, Xs),
append(_, Ys, Is).
append("w", _, W), % or: "w" = [C], W = [C|_]
append(_, W, Ys).
它的可读性更好吗?我想不是。
[o,k]
的部分对我来说看起来有点不自然,但它会是:
list_ret(Xs, Ys) :-
list_suspect(Xs, Ys).
list_ret(Xs, Ys) :-
\+ list_suspect(Xs,_),
Ys = "ok".
答案 1 :(得分:2)
一个班轮,使用append / 2
suspect(L, S) :-
length(S, 5), append([S,_,S], L), memberchk(w, S) -> true ; S = [o,k].
编辑如false所示,定义是错误的(缺少steadfastness?):修改后的规则
suspect(L, R) :-
length(S, 5), append([S,_,S], L), memberchk(w, S) -> S = R ; R = [o,k].
答案 2 :(得分:2)
Prolog是一种声明性语言:根据约束描述解决方案并让引擎完成工作。
我们可以确定列表中的成员资格:
contains( [X|Xs] , X ) :- ! .
contains( [_|Xs] , X ) :- contains(Xs,X) .
我们可以使用内置谓词append/3
确定列表第一个元素是否与其最后一个元素相同:
list_starts_and_ends_with_identical( [X|Xs] ) :-
append( [X|_] , [X] , [X|Xs] )
.
或者,如果你想自己动手:
list_starts_and_ends_with_identical( [A|Xs] ) :-
list_ends_with( Xs , A )
.
list_ends_with( [A] , A ) .
list_ends_with( [B,C|D] , A ) :-
list_ends_with( [C|D] , A )
.
我们可以枚举所需长度的子列表,如下所示:
sublist_of_length( Xs, L , Ys ) :- % to enumerate sublists of the desired length,
integer(L) , % - validate that the length is an integer, and
L > 0 , % - validate that the length is positive, and
length(Ys,L) , % - construct a list of unbound variables of the desired length, and
sl(Ys,L) % - invoke the helper
. %
sl( [X|Xs] , L ) :- % to enumerate sublists,
append( L , _ , [X|Xs] ) % - simply get the prefix of the desired length
. %
sl( [_|Xs] , L ) :- % on backtracking,
sl( Xs , L ) % - just recurse down on the tail of the list, discarding the first element.
.
然后,我们所要做的就是组装部件:
suspect_sublist( Xs , L ) :- % the source list Xs contains a suspect sublist L, IF...
sublist_of_length( Xs , 5 , L ) , % - L is a sublist of Xs having length 5, and
contains( L , w ) , % - L contains the atom 'w', and
list_starts_and_ends_with_identical( L ) , % - the first element of L is identical to the last.
. % Easy!