给定元素列表,将每个元素复制N次

时间:2019-05-27 05:26:49

标签: prolog

我必须像这样将每个元素复制n次: ?-复制([a,b,c],2,X)。 -> X = [a,a,b,b,c,c] ?-复制([a,b,c],3,X)。 -> X = [a,a,a,b,b,b,c,c,c]

到目前为止,我已经尝试了所有信息,我唯一能做的就是确定哪一个是最重复的元素:

%List of tuples, keeps track of the number of repetitions.
modify([],X,[(X,1)]).
modify([(X,Y)|Xs],X,[(X,K)|Xs]):- K is Y+1.
modify([(Z,Y)|Xs],X,[(Z,Y)|K]):- Z =\= X, modify(Xs,X,K).

highest((X1,Y1),(_,Y2),(X1,Y1)):- Y1 >= Y2.
highest((_,Y1),(X2,Y2),(X2,Y2)):- Y2 > Y1.

maxR([X],X).
maxR([X|Xs],K):- maxR(Xs,Z),highest(X,Z,K).

rep([],R,R).
rep([X|Xs],R,R1):-modify(R,X,R2),rep(Xs,R2,R1).

maxRepeated(X,R):- rep(X,[],K),maxR(K,R).


?- maxRepeated([1,3,3,4,3,2] ,X).
X = (3, 3) .

?- maxRepeated([1,2,3,4,5,6] ,X).
X = (1, 1) .

2 个答案:

答案 0 :(得分:1)

您想做什么? 取列表中的每个元素X,获得N X的列表,并使用其余列表的过程创建一个新列表! 如何获得N个元素X的列表?

replicate_one(X, N, Out) :-
    length(Out, N),
    maplist(=(X),Out).

现在,如何处理输入的每个元素,可以使用模式[Head | Tail]轻松完成:

replicate([Head|Tail], N, Out) :-
    % I replicate the rest of the list
    replicate(Tail, N, Tmp1),
    % I replicate the first element of the list
    replicate_one(Head, N, Tmp2),
    % I concatenate the 2 results
    append(Tmp2, Tmp1, Out).

使用复制时,输入每次都会松散一个元素,因此您必须有一个用于空列表的过程:

replicate([], _N, []).

现在:

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

答案 1 :(得分:0)

我们可以将问题分为两个问题:

  1. 使用我们实现的N谓词生成X元素replicate_item/3的列表;和
  2. 对每个元素执行此操作,然后将结果连接到名为replicate/3的prdicate中。

@joel76已经为replicate_item/3提供了很好的实现。我只会更改参数的顺序:

replicate_item(N, X, List) :-
    length(List, N),
    maplist(=(X), List).

现在,我们的replicate/3证书可以遍历列表,对于每个元素,请使用replicate_item/3生成子列表。然后,我们可以使用append/2 [swi-doc]

replicate(LA, N, List) :-
    maplist(replicate_item(N), LA, LL),
    append(LL, List).