【问题标题】:Perform list conversion,Prolog执行列表转换,Prolog
【发布时间】:2020-12-24 06:10:45
【问题描述】:

[a,a,a,a,b,c,c,a,a,d,e,e,e,e] => [[4,a],b,[2,c],[ 2,a],d,[4,e]]。 请帮我解决这个问题 我有这段代码,但我不知道如何将它带到所需的代码中,或者如何以不同的方式或更容易地完成它:

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).

【问题讨论】:

  • Res 进行第二次传递,将[X,1] 重写为X 并在dif(Y, 1) 的情况下保留[X,Y] 怎么样?

标签: prolog


【解决方案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).

给予

?- 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] 

我使用了来自 swi-prolog 的pairs 来表示和元素及其长度。您可以根据需要将其更改为列表,只需将上述代码中的任何A-B 实例替换为[A, B]

【讨论】:

    【解决方案2】:

    这是一个学习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).
    

    结果:

    ?- 开始(输出)。

    Out = [[1, b], [1, d], [2, c], [4, e], [6, a]]。

    【讨论】:

    • Op 想要一个元素的运行不计数。
    • 糟糕!没看懂
    【解决方案3】:

    好的,为了减少混淆:我首先看到了您的other 问题,您或多或少地要求将答案从rajashekar 转换为您想要的格式。我同意 rajashekar 的观点,所以我不会为你做所有的工作,但它仍然可以简化代码,所以这里离你的目标更近了一步:

    起初我会删除第四个参数。只需 3 个参数就可以做到这一点,您甚至不必反转您的 Acc

    其次,您希望使用列表写入 ([a, 4]) 而不是减号对写入 (a-4)。

    第三,您希望有一种特殊情况,即显示单个元素而没有列表表示法(b 而不是[b, 1])。

    这是应用更改 1 和 3 时的代码;第 2 部分您可以通过阅读 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.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-22
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多