Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 在列表末尾插入,其中列表的元素也是列表_List_Prolog - Fatal编程技术网

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.

在另一个分支的末端进行切割是完全无用的:也就是说,尽量避免切割。他们只需要表达否定,这是一个相当高级的话题。