插入列表末尾的列表元素也是列表

时间:2016-03-16 05:27:23

标签: list prolog

该程序需要执行以下操作

输入:

encode_modified([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X).       

输出:

X = [[4,a],[1,b],[2,c],[2,a],[1,d],[4,e]]    

我写了下面这段代码。然而,它反过来给我列表。我不希望在最后手动反转列表。我相信我可以通过修改insertIntoList()函数来获得解决方案。然而,我坚持如何选择列表作为主列表的元素。

encode_modified([H|In],Out) :-
   encode(In,H,1,Out,[]).

encode([],Prev,Count,Temp1,Temp) :-
   createListFromPair(Count,Prev,Pair),
   insertIntoList(Pair,Temp,Temp1).
encode([H|In],Prev,Count,Out,Temp) :-
   (  H = Prev, Count1 is Count+1,
      encode(In,H,Count1,Out,Temp)
   ;
      createListFromPair(Count,Prev,Pair),
      insertIntoList(Pair,Temp,Temp1),
      encode(In,H,1,Out,Temp1),
      !
   ).

createListFromPair(H1,H2,[H1,H2]).

insertIntoList(H,Temp,[H|Temp]).

2 个答案:

答案 0 :(得分:1)

您的代码可以按照需要行事,简化后:

encode_modified([H|In],Out) :- encode(In,H,1,Out).

encode([],Prev,Count,[[Count,Prev]]).
encode([H|In],H,Count,Rest) :-
    Count1 is Count+1,
    encode(In,H,Count1,Rest).
encode([H|In],Prev,Count,[[Count,Prev]|Rest]) :-
    H \= Prev,
    encode(In,H,1,Rest).

答案 1 :(得分:1)

您也可以在没有辅助谓词的情况下执行此操作。您的原始命名(createListFromPairinsertIntoList)意味着您正在考虑命令式,就像在C中编码一样。如果您认为关系,您可以拥有一个在任一方向都起作用的谓词:

encoded([], []).
encoded([X], [[1,X]]).
encoded([X,Y|T], [[1,X]|R]) :-
    dif(X, Y),
    encoded([Y|T], R).
encoded([X,X|T], [[N,X]|R]) :-
    N #> 1,
    N #= N1 + 1,
    encoded([X|T], [[N1,X]|R]).

在这里你会得到:

?- encoded([a, a, b, b, b], L).
L = [[2,a],[3,b]] ;
false.

?- encoded(L, [[2,a],[3,b]]).
L = [a, a, b, b, b] ;
false.

?-

对于表示,破折号仿函数比两个元素的子列表更有效,更易于阅读:

encoded([], []).
encoded([X], [1-X]).
encoded([X,Y|T], [1-X|R]) :-
    dif(X, Y),
    encoded([Y|T], R).
encoded([X,X|T], [N-X|R]) :-
    N #> 1,
    N #= N1 + 1,
    encoded([X|T], [N1-X|R]).

?- encoded([a, a, b, b, b], L).
L = [2-a, 3-b] ;
false.