2014-09-02 78 views
3

所以我校園教授要求我們解決這個練習,但有點困難,現在我正在嘗試2天。無論如何這裏是:prolog上的名單練習

我給了一個例子列表[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). 
+3

請告訴我們你已經嘗試的東西,在這裏你就完蛋了。 – 2014-09-02 20:25:09

+0

'add(H,[H | T])。 (H,L1), 數字1是數字-1, finder查詢(T,數字1,L1,L2,X)()數字1是數字-1, 查找器(T,N號碼,L1,L2,X) )。' 我嘗試「使用」這個從列表中得到前五個字符... 我知道它**不是**太多 – Nick 2014-09-02 20:46:23

回答

2

Prolog是一個聲明式語言:用約束描述解決方案並讓引擎完成工作。

我們可以在列表中確定成員從而:

contains([X|Xs] , X) :- ! . 
contains([_|Xs] , X) :- contains(Xs,X) . 

我們能夠確定是否列出第1個要素是使用內置的謂詞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) 
    . 

而且我們可以枚舉su所需長度的blists像這樣:

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! 
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". 
+0

因爲我的水平/ prolog的經驗是可怕的我真的沒有得到1碼。無論如何,這個代碼我嘗試獲得前五個字符,但它給了我一個錯誤。這裏是代碼: 'add(H,[H | T])。 取景器([H | T],Νumber,L1): - \t數量> 0, \t添加(H,L1), \t數字1是數字1, \t取景器(T,Νumber1,L1).' 非常感謝! :) – Nick 2014-09-02 21:08:29

+0

這個問題沒有涉及數字。這只是列表。 – false 2014-09-02 21:16:08

+0

看到我的第二個版本沒有語法版本。 – false 2014-09-02 21:17:04

2

一個襯墊,使用append/2

suspect(L, S) :- 
    length(S, 5), append([S,_,S], L), memberchk(w, S) -> true ; S = [o,k]. 

編輯通過虛假指出,定義是越野車(缺少steadfastness?):修改後的規則

suspect(L, R) :- 
    length(S, 5), append([S,_,S], L), memberchk(w, S) -> S = R ; R = [o,k]. 
+0

即使我不把我的名單上的字母「W」,這種方法總是正確的。感謝:) – Nick 2014-09-02 21:45:10

+0

@Nick:這個定義成功的可疑([a,b,c,d,w,n,i,c,k,a,b,c,d,w],[o,k]) ';但它應該失敗。 – false 2014-09-03 12:55:49