检查列表是否由 X 的 N 个实例组成(重复 X N 次) [英] Check if a list is made up of N instances of X (repeat X N times)

查看:19
本文介绍了检查列表是否由 X 的 N 个实例组成(重复 X N 次)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个查询,例如:

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.

对于第二个示例,我需要将列表中的元素应用 4 次绑定到 W.

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.

这篇关于检查列表是否由 X 的 N 个实例组成(重复 X N 次)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆