【问题标题】:List exercise on prolog在 prolog 上列出练习
【发布时间】:2014-09-09 04:25:50
【问题描述】:

所以我的校园教授让我们解决这个练习,但有点难,我现在正在尝试 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).

【问题讨论】:

  • 请向我们展示您的尝试,以及您遇到的问题。
  • add(H,[H|T]). finderSuspect([H|T],Νumber,L1,L2,X):- Number>0 add(H,L1), Number1 is Number - 1, finderSuspect(T,Νumber1,L1,L2,X). 我尝试“使用”它来获取列表中的前五个字符...我知道它没有很多

标签: list prolog


【解决方案1】:

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!

【讨论】:

    【解决方案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".
    

    【讨论】:

    • 因为我的 prolog 水平/经验很糟糕,我没有真正得到第一个代码。无论如何,在这段代码中,我尝试获取前五个字符,但它给了我一个错误。这是代码:add(H,[H|T]). finder([H|T],Νumber,L1):- Number>0, add(H,L1), Number1 is Number - 1, finder(T,Νumber1,L1). 非常感谢!! :)
    • 这个问题没有涉及到数字。它只是关于列表。
    • 查看我的第二个版本,了解没有语法的版本。
    • 那么要获得前五个字母我需要改变什么?我使用“数字”为这个变量赋予数字 5,以便调用 finder 5 次!
    • 这里有太多的误解。只需查看上面的第二个版本,它不使用 DCG,而是简单地附加
    【解决方案3】:

    一个班轮,使用append/2

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

    edit 如 false 所述,定义有问题(缺少 steadfastness ?):修改后的规则

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

    【讨论】:

    • 即使我没有将字母“w”放在我的列表中,这种方法也总是正确的。谢谢:)
    • @Nick: 这个定义对 suspect([a,b,c,d,w,n,i,c,k,a,b,c,d,w],[o,k]) 成功;但它应该失败。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多