本文介绍了Prolog - 在列表中查找相邻元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试定义一个谓词 adjacent(X, Y, Zs) 如果 X 和 Y 在列表中相邻,则该谓词为真.我的代码目前是这样的:

I'm trying to define a predicate adjacent(X, Y, Zs) that is true if X and Y are adjacent in a list. My code is currently this:

adjacent(_, _, []).
adjacent(X, Y, [X, Y|Tail]) :-
  adjacent(X,Y, Tail).

它适用于 adjacent(c, d, [a, b, c, d, e]) 的基本情况,但由于基本情况,所有其他情况也返回 true,而我一直坚持这一点.

It works for the basic case of adjacent(c, d, [a, b, c, d, e]), but due to the base case, every other case returns true as well, and I'm stuck on that.

另一个问题是,如果 X 不等于列表头部的第一部分,那么它会跳过 X 和 Y 并转到下一个X";例如,如果 c 不等于 a,那么它会跳过 ab 并检查是否c 等于 c.这是有问题的,例如,列表是

The other problem is that if X is not equal to the first part of the list's head, then it skips past both X and Y and goes to the next 'X'; e.g., if c isn't equal to a, then it skips past both a and b and checks if c is equal to c. This is problematic when, for example, the list is

[a, c, d, e]

因为它最终从不检查 c(我相信).

because it ends up never checking c (I believe).

我不知道如何调和这两个问题,并将我对需要发生的事情的逻辑理解转化为代码.

I'm pretty lost on how to reconcile the two issues and turn my logical understanding of what needs to occur into code.

感谢 Christian Hujer 的回答,我的基本情况错误已得到纠正,所以现在我只停留在第二个问题上.

Thanks to Christian Hujer's answer, my base case mistake has been corrected, so now I'm just stuck on the second issue.

推荐答案

在原解决方案尝试中:

adjacent(_, _, []).
adjacent(X, Y, [X, Y|Tail]) :-
    adjacent(X,Y, Tail).

正如@ChristianHujer 指出的那样,第一个子句不应该存在,因为它不是真的.空列表不应有相邻元素.

As @ChristianHujer points out, the first clause should not be there because it isn't true. The empty list should have no adjacent elements.

第二个子句也有问题.它表明 XY 在列表中是相邻的,但随后递归并且不只是成功.一个适当的子句应该是:

The second clause is also problematic. It shows that X and Y are adjacent in the list, but then recurses and doesn't just succeed. A proper clause should be:

adjacent(X, Y, [X,Y|_]).

这表示如果 XY 是列表中的前两个元素,则它们在列表中是相邻的,无论尾部是什么.这也形成了一个适当的基本情况.那么你的一般递归子句应该处理其余的情况:

Which says that X and Y are adjacent in the list if they're the first two elements in the list, regardless of what the tail is. This also forms a proper base case. Then your general, recursive clause should take care of the rest of the cases:

adjacent(X, Y, [_|Tail]) :-
    adjacent(X, Y, Tail).

这表示如果 XY[_|Tail] 中相邻,则它们在 Tail.这可以解决您遇到的第二个问题.

This says that X and Y are adjacent in [_|Tail] if they're adjacent in Tail. This takes care of the second problem you were encountering.

因此,整个解决方案将是:

Thus, the whole solution would be:

adjacent(X, Y, [X,Y|_]).
adjacent(X, Y, [_|Tail]) :-
    adjacent(X, Y, Tail).

这将成功的次数与 XY 按此顺序一起出现在列表中的次数相同.


这也可以通过 DCG 自然解决(尽管@repeat 的基于 append/3 的解决方案更简洁):

This will succeed as many times as X and Y appear together, in that order, in the list.


This is also naturally solvable with a DCG (although @repeat's append/3 based solution is more concise):

adjacent(X, Y) --> ..., [X, Y], ... .
... --> [] | [_], ... .

adjacent(X, Y, L) :- phrase(adjacent(X, Y), L).


| ?- adjacent(b, c, [a,b,c,d]).

true ? a

(1 ms) no
| ?-

这篇关于Prolog - 在列表中查找相邻元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 05:53