List 在列表末尾插入,其中列表的元素也是列表
该程序需要执行以下操作 输入:List 在列表末尾插入,其中列表的元素也是列表,list,prolog,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]] 我已经编写了以下代码。然而,它给了我相反的清单。我不希望在最后手动反转列表。我相信我可以通过修改insertionList()函数来获得解决方案。然而,我被困在如何选择一个列表作为主列表的一个元素 encode_modified([H|In],Out
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]]
我已经编写了以下代码。然而,它给了我相反的清单。我不希望在最后手动反转列表。我相信我可以通过修改insertionList()函数来获得解决方案。然而,我被困在如何选择一个列表作为主列表的一个元素
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]).
简化后,您的代码可以按要求运行:
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).
也可以在不使用辅助谓词的情况下执行此操作。您最初的命名(
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.
在另一个分支的末端进行切割是完全无用的:也就是说,尽量避免切割。他们只需要表达否定,这是一个相当高级的话题。