我有这个谓词 repeat/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]
我认为解决方案是让我遍历列表并为每个元素重复 n 次,但我不知道如何做。
我尝试的一个想法是让我传递给谓词的数字在达到 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).
这没有成功。我现在知道我是否在正确的轨道上。任何帮助将不胜感激。
最佳答案
虽然肯定还有一些其他问题,但最重要的问题是您递减 N
直到它达到零以重复第一个元素。但是当它归零之后,当然你就不能再得到原来的N
了。
那么我们如何存储原始的N
呢?我们可以简单地引入一个新的谓词 repeat/4
,其中:
repeat(L, N, LN) :-
repeat(L, N, N, LN).
所以我们通过复制N
将repeat/3
重定向到repeat/4
。我们的想法是,我们将只减少参数中的一个。从参数达到零的那一刻起,我们将通过从第二个 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).
关于list - 在序言中依次迭代列表元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46590554/