获取在列表中重复的连续元素n次序言

时间:2016-11-25 11:33:06

标签: list prolog

我正在尝试使用返回元素的函数在列表中重复n次。像这样:

repeat([a,a,c,a,b,b,b,b,a,g],4,E).

结果应为E = b。最简单的方法是什么?这4个元素也必须是连续的。

获取所有元素出现的代码计数:

precondition(Clause):-
    Clause =.. [_|ARGS],
    ( maplist(var,ARGS) -> true; Clause ).

count( [], [] ).

count( [X], [(X,1)] ) :- !.

count( [H|Q], [(H,1),(HR,NR)|QR] ) :-
    count( Q, [(HR,NR)|QR] ),
    H \= HR,
    !.

count( [H|Q], [(H,NR)|QR] ) :-
    precondition( succ(N,NR) ),
    count( Q, [(H,N)|QR] ),
    succ(N,NR).

2 个答案:

答案 0 :(得分:3)

如果您拥有类似的列表,则可以使用member/2

?- R = [(a, 2), (c, 1), (a, 1), (b, 4), (a, 1), (g, 1)], 
   member((Element, 4), R).
R = [(a, 2),  (c, 1),  (a, 1),  (b, 4),  (a, 1),  (g, 1)],
Element = b ;
false.

如果您制作了像[a-2, c-1, a-1, ...]这样的列表,那么它会更像Prolog一样,然后使用member(Element-4, R)代替。像(a, b, ...)这样的术语像其他语言一样的元组,a-b通常用作一对。

如果我使用SWI-Prolog提供的库,我将如何做到这一点:

L = [a,a,c,a,b,b,b,b,a,g], N = 4,
    pairs_keys_values(Ps, L, L),
    group_pairs_by_key(Ps, G),
    include([X-Xs]>>length(Xs, N), G, R),
    member(Element-_, R).
% some results you don't need
Element = b.

include行不是严格必要的,但它避免了不必要的选择点。

答案 1 :(得分:2)

可能还需要做一些测试,但这是我的解决方案(比较运算符是整数):

repeat([L], 0, X) :- L \= X.
repeat([L], 1, X) :- L == X.
repeat([X|T], C, X) :- C1 is C - 1, repeat(T, C1, X).
repeat([_|T], C, X) :- repeat(T, C, X).

编辑我注意到为您的示例提供的解决方案也将返回E=a,但它不应该。所以这是新方法:从给定生成所有子列表,检查生成的列表是否包含相同的元素,然后检查这些列表的长度是否是第二个参数C

sublist([],[]).
sublist([H|T], [H|Q]) :- sublist(T,Q).
sublist([_|T], Q) :- sublist(T,Q).

sameelements([X], X).
sameelements([X|T], X) :- sameelements(T, X).

len([], 0).
len([_|T], C) :- len(T, C1), C is C1 + 1.

repeat(L, C, X) :- sublist(L, SL), len(SL, C), sameelements(SL, X).