【问题标题】:Prolog program firstlast without recursion?Prolog程序firstlast没有递归?
【发布时间】:2018-10-12 11:27:32
【问题描述】:

如果列表具有相同的第一个和最后一个元素但不使用附加谓词进行递归,我将如何编写如下所示的成功的序言程序?

firstlast([H,H]).
firstlast([F,_|T]) :- firstlast([F|T]).

示例查询:

?- firstlast([1,2,3,1]).
Yes

?- firstlast([1,2,3]).
No

【问题讨论】:

  • 提示:你可以使用append(_, [Last], L)获取列表的最后一个元素Last
  • 此外,我的印象是,您的第一次尝试并未涵盖边缘情况:单例列表。
  • 为什么不用递归?

标签: prolog append


【解决方案1】:

我认为您的谓词缺少一个边缘情况:singleton 列表:在一个只有一个元素的列表中,第一个和最后一个元素是相同的。

firstlast([_]).
firstlast([H,H]).
firstlast([F,_|T]) :- firstlast([F|T]).

您可以使用append/3 来获取最后一个元素:

last(L, Last) :-
    append(_, [Last], L).

由于将[Last] 附加到某个列表,因此这项工作只能产生以Last 作为最后一个元素的列表。由于该列表是L,并且append/3 可以朝那个方向工作,因此我们可以获得最后一个元素。例如:

?- append(_, [Last], [1,4,2,5]).
Last = 5 ;
false.

我认为有了这个提示,你应该可以不用递归来解决问题。

【讨论】:

  • 我对 prolog 还是很陌生。这是我的第一个程序之一,我仍然不太确定如何在没有递归的情况下做到这一点......?
  • @DovRoyal:你需要找出第一个和最后一个元素是否相同,那么你怎么做呢?您获得第一个项目,您获得 last 项目(如此处所示),然后检查两者是否相等......
【解决方案2】:

如果您不打算使用递归,则需要使用某种预定义的 Prolog 谓词。一个简单的解决方案可以使用reverse/2

firstlast([H|T]) :- reverse([H|T], [H|_]).

这创建了一个很好的通用解决方案:

| ?- first_last(L).

L = [_] ? ;

L = [A,A] ? ;

L = [A,_,A] ? ;

L = [A,_,_,A] ? ;

L = [A,_,_,_,A] ?
...

如果要确保列表至少有两个元素,则使用附加元素:

firstlast([X,Y|T]) :- reverse([X,Y|T], [X|_]).

产量:

| ?- firstlast(L).

L = [A,A] ? ;

L = [A,_,A] ? ;

L = [A,_,_,A] ? ;

L = [A,_,_,_,A] ?
...

【讨论】:

    猜你喜欢
    • 2018-04-24
    • 2021-03-24
    • 1970-01-01
    • 2017-04-26
    • 2011-12-09
    • 2014-06-16
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多