该程序需要执行以下操作
输入:
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]).
答案 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)
您也可以在没有辅助谓词的情况下执行此操作。您的原始命名(createListFromPair
和insertIntoList
)意味着您正在考虑命令式,就像在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.