在prolog中轮流迭代列表元素

时间:2017-10-05 16:27:34

标签: list prolog

我有这个谓词重复/ 3我需要构建。它应该重复列表中的所有元素n次。例如:

?- repeat([a,b,a,a,c],2,X).

会生产 X = [a,a,b,b,a,a,a,a,c,c]。

我为其编写的当前代码如下:

repeat([],_,[]).
repeat(_,0,[]).
repeat([A],Int,[A|X]):- Int1 is Int-1, repeat([A],Int1,X).
repeat(A,1,A).
repeat([A|Tail],Int,[A|X]):- Int1 is Int-1, repeat([A|Tail],Int1,X).

它将返回:
1)给出空列表时的空列表 2)在给出数字0作为参数时的空列表 3)一个字母n次 4)给定清单一次 现在,我遇到的问题是最后一行代码 5)这条线目前为我做的是在重复第一个元素n次之后返回列表中的所有元素 示例:

?- repeat([a,b,b,c],3,X).
X = [a, a, a, b, b, c]  

我认为解决方案是让我通过列表,并且每个元素都重复了很多次,但我没有任何关于如何做的线索。
我尝试过的一个想法就是让我传入谓词的数字在达到1后变成原文,然后使用尾部继续谓词:

repeat([],_,[]).
repeat(_,0,[]).
repeat([A],Int,[A|X]):- Int1 is Int-1, repeat([A],Int1,X).
repeat([A|Tail],1,[A|X]):- repeat(Tail,Int,X).  % The line where I made a change.
repeat([A|Tail],Int,[A|X]):- Int1 is Int-1, repeat([A|Tail],Int1,X).

这没有用。我现在知道我是否正确地走上正轨。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

虽然肯定还有一些其他问题,但最重要的问题是你递减N,直到它达到零以重复第一个元素。但是当它达到零之后,你当然不再能获得原始的N

那么我们如何存储原始N?我们可以简单地引入一个新的谓词repeat/4,其中包含:

repeat(L, N, LN) :-
    repeat(L, N, N, LN).

因此,我们通过复制repeat/3repeat/4重定向到N。我们的想法是,我们只减少参数的一个。从参数命中零的那一刻起,我们将通过从第二个N(我们不减量)中获取值来“重置”参数。

所以现在我们只需要解决repeat/4。如果我们到达列表的末尾,那么 - 无论N的值如何 - 重复都是空列表:

repeat([], _, _, []).

如果第一个N已达到零,我们将继续执行列表的下一个元素,并重置N

repeat([_|T], 0, N, LN) :-
    repeat(T, N, N, LN).

最后如果我们还没有达到零,我们当然会在第一个列表的头部前面加上结果:

repeat([H|T], A, N, [H|LN]) :-
    A > 0,
    A1 is A-1,
    repeat([H|T], A1, N, LN).

如果我们把它们放在一起,我们就会得到:

repeat(L, N, LN) :-
    repeat(L, N, N, LN).

repeat([], _, _, []).
repeat([_|T], 0, N, LN) :-
    repeat(T, N, N, LN).
repeat([H|T], A, N, [H|LN]) :-
    A > 0,
    A1 is A-1,
    repeat([H|T], A1, N, LN).