Perform list conversion,Prolog

扶醉桌前 提交于 2021-02-10 06:57:17

问题


[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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!