问题
[a,a,a,a,b,c,c,a,a,d,e,e,e,e] => [[4,a],b,[2,c],[2,a],d,[4,e]]. please help me solve this problem I have this code, but I do not know how to bring it to the one that is required or how can it be done differently or easier:
p([]):- !.
p( [X] ):- !, write(X).
p( [X | T] ):-!, write(X), write(", "), p(T).
first_letter([H], Let, Num, Mid, Res):-
( H = Let, New_num is Num +1,
G = [Let], Prom = [New_num | G],
Res = [Prom | Mid], !
; true
),
( H \= Let,New_num is 1,
G = [Let], Prom = [Num | G], New_mid = [Prom | Mid],
SG = [H], Sec_Prom = [New_num | SG],
Res = [Sec_Prom | New_mid],
!
; true
).
first_letter([H | T], Let, Num, Mid, Res):-
( H = Let,New_Num is (Num + 1),
first_letter(T, Let, New_Num, Mid, Res),
!
; true
),
( H \= Let, G = [Let], Prom = [Num | G],
New_mid = [Prom | Mid],
first_letter(T, H, 1, New_mid, Res),
!
; true
).
nreverse([T], Res):- Res = [T], !.
nreverse([H | T], Res):-
nreverse(T, Resal),
append(Resal, [H], Res). %nehvost
start:-
T = [a,a,a,a,b,c,c,a,a,d,e,e,e,e], T = [H | _],
first_letter(T, H, 0, [], Res),
nreverse(Res, End),
p(End).
回答1:
squeeze([], []).
squeeze([X|Xs], Ys) :-
squeeze(Xs, X-1, [], Ys).
squeeze([], Current, Acc, Ys) :- reverse(Ys, [Current|Acc]).
squeeze([X|Xs], X-N, Acc, Ys) :-
N1 is N+1,
squeeze(Xs, X-N1, Acc, Ys).
squeeze([X|Xs], C-N, Acc, Ys) :-
dif(X,C),
squeeze(Xs, X-1, [C-N|Acc], Ys).
gives
?- squeeze([a,a,a,a,b,c,c,a,a,d,e,e,e,e], X).
X = [a-4, b-1, c-2, a-2, d-1, e-4]
I have used pairs
from swi-prolog to represent and element and its length. You can change it to list if you want, just replace any instance of A-B
with [A, B]
in the above code.
回答2:
It's an exercice to learn fold/4
:- use_module(library(lambda)).
start(Out) :-
T = [a,a,a,a,b,c,c,a,a,d,e,e,e,e],
foldl(\X^Y^Z^(nth0(_, Y , [A,X], R)
-> A1 is A + 1,
Z = [[A1, X] | R]
; Z = [[1, X] | Y]),
T, [], Out_),
sort(Out_, Out).
Result :
?- start(Out).
Out = [[1, b], [1, d], [2, c], [4, e], [6, a]].
回答3:
Ok, to reduce confusion: I saw your other question first where you more or less ask about to turn the answer from rajashekar to your desired format. I agree with rajashekar, so I won't do all the work for you but it still tickles to simplify the code, so here a step closer to your goal:
At first I would remove the fourth argument. It is possible to do it with just 3 arguments and you don't even have to reverse your Acc
.
Second, you want to have a list-writing ([a, 4]
) instead of a minus-pair-writing (a-4
).
Third you want to have a special case where single elements are displayed without the list notation (b
instead of [b, 1]
).
This is the code when you apply the changes 1 and 3; part 2 you can just do by reading the answer by rajashekar:
squeeze1([], []).
squeeze1([X|Xs], Ys) :-
squeeze1(Xs, X-1, Ys).
squeeze1([], Current, [Current]).
squeeze1([X|Xs], X-N, Acc) :-
N1 is N+1,
squeeze1(Xs, X-N1, Acc).
squeeze1([X|Xs], C-N, [C-N|Acc]) :-
N>1,
dif(X,C),
squeeze1(Xs, X-1, Acc).
squeeze1([X|Xs], C-1, [C|Acc]) :-
dif(X,C),
squeeze1(Xs, X-1, Acc).
?- squeeze1([a,a,a,a,b,c,c,a,a,d,e,e,e,e], X).
X = [a-4, b, c-2, a-2, d, e-4] ;
false.
来源:https://stackoverflow.com/questions/65434634/perform-list-conversion-prolog