您好,我试图在Prolog中制作一个程序,给定一个列表,它按如下方式计算列表中每个连续元素的出现次数:

count(1,[1,1,1,2,2,2,3,1,1],0,X)


结果将是X=[ [1,3],[2,3],[3,1][1,2] ]
也就是每个子列表都是[element,occurrences]

就我而言,我认为基本情况存在问题,但我无法解决。你能帮助我吗?

%append an element to a list
append([ ],Y,Y).
append([X|Xs],Ys,[X|Zs]):-append(Xs,Ys,Zs).

%c is the counter beginning with 0
count(_,[],_,[]).
count(X,[X],C,[L]):-count(X,[],C,[L|[X,C]]).

%increase counter
count(X,[X|Tail],C,L):-Z is C+1,count(X,Tail,Z,L).
count(X,[Head|Tail],C,[L]):-append(L,[X,C],NL),count(Head,Tail,1,NL).

最佳答案

这是基于clpfd的游程长度编码的另一种尝试!

:-use_module(library(clpfd))。


基于if_/3(=)/3,我们定义list_rle/2

list_rle([],[])。
list_rle([X | Xs],[N * X | Ps]):-
list_count_prev_runs(Xs,N,X,Ps)。

list_count_prev_runs(Es,N,X,Ps):-
N#> 0,
N#= N0 + 1,
list_count_prev_runs_(Es,N0,X,Ps)。

list_count_prev_runs _([],0,_,[])。
list_count_prev_runs _([E | Es],N,X,Ps0):-
if_(X = E,
list_count_prev_runs(Es,N,X,Ps0),
(N = 0,Ps0 = [M * E | Ps],list_count_prev_runs(Es,M,E,Ps)))。


查询样例:


编码/解码#1

?-list_rle([a,a,b,c,c,c,d,e,e],Ys)。
Ys = [2 * a,1 * b,3 * c,1 * d,2 * e]。

?-list_rle(Xs,[2 * a,1 * b,3 * c,1 * d,2 * e])。
Xs = [a,a,b,c,c,c,d,e,e]
;假。

编码/解码#2

?-dif(A,B),dif(B,C),dif(C,D),dif(D,E),list_rle([A,A,B,C,C,C,D,E,E ],Ys)。
Ys = [2 * A,1 * B,3 * C,1 * D,2 * E],dif(A,B),dif(B,C),dif(C,D),dif(D,E )。

?-list_rle(Xs,[2 * A,1 * B,3 * C,1 * D,2 * E])。
Xs = [A,A,B,C,C,C,D,E,E],dif(A,B),dif(B,C),dif(C,D),dif(D,E)
;假。

一般的东西怎么样?

?-list_rle([A,B,C,D],Xs)。
Xs = [4 * A],A = B,B = C,C = D
; Xs = [3 * A,1 * D],A = B,B = C,dif(C,D)
; Xs = [2 * A,2 * C],A = B,dif(B,C),C = D
; Xs = [2 * A,1 * C,1 * D],A = B,dif(B,C),dif(C,D)
; Xs = [1 * A,3 * B],dif(A,B),B = C,C = D
; Xs = [1 * A,2 * B,1 * D],dif(A,B),B = C,dif(C,D)
; Xs = [1 * A,1 * B,2 * C],dif(A,B),dif(B,C),C = D
; Xs = [1 * A,1 * B,1 * C,1 * D],dif(A,B),dif(B,C),dif(C,D)。

10-06 09:26