检查列表是否由N个X实例组成(重复X N次) [英] Check if a list is made up of N instances of X (repeat X N times)
问题描述
给出一个查询,例如:
containsN(4,2,Z).
我应该得到:Z = [2,2,2,2].
I should get: Z = [2,2,2,2].
或
containsN(4,W,[3,3,3,3])
我应该得到:W = 3.
I should get: W = 3.
换句话说,对于第一个示例,在绑定到Z的列表中,我需要4个实例(2个实例).
So in other words, for the first example I need 4 instances of 2 in a list bound to Z.
对于第二个示例,我需要将列表中的元素应用到绑定到W的4次.
For the second example I need the element in the list applied 4 times bound to W.
到目前为止,我的尝试导致了无限循环:
My attempt so far results in an infinite loop:
containsN(Y,W,Z) :- contains_helper(Y,W,Z).
contains_helper(0,_,_).
contains_helper(Y,W,[H|T]) :- W = H, Y0 is Y - 1, contains_helper(Y0,W,T).
想法是,我调用一个辅助函数,以便可以逐个检查Z的元素.当计数器达到0时,我知道列表为真,因为每次迭代H =W.但是,我遇到了无限循环.
The idea is, I call a helper function so that I can check the elements of Z one by one. When the counter reaches 0 I know the list is true because for each iteration H = W. However, I'm getting an infinite loop.
推荐答案
如果您希望谓词尽可能通用(我将其重命名为repeat/3
)
If you want the predicate to be as general as possible (and I renamed it to repeat/3
)
?- repeat(X, N, L).
N = 0, L = [] ;
N = 1, L = [X] ;
...
您可以使用length/2
的漂亮属性,如下所示:
You can use the nice properties of length/2
, like this:
% True when L is a list with N repeats of X
repeat(X, N, L) :-
length(L, N),
maplist(=(X), L).
在这里,length(L, N)
可以检查列表的长度,或者生成所需长度的列表,或者在回溯时生成长度增加的列表.
Here, length(L, N)
can check for the list's length, or generate a list of the desired length, or generate lists of increasing length upon backtracking.
如果列表L的每个元素与变量X统一,则maplist(=(X), L)
将成功.您可以将其编写为:
The maplist(=(X), L)
will succeed if each element of the list L unifies with the variable X. You could have written it as:
foo([], _).
foo([X|Xs], X) :-
foo(Xs, X).
但我认为这不是必需的.
but I don't think this is necessary.
这篇关于检查列表是否由N个X实例组成(重复X N次)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!